Expansion du support!

36

Votre défi consiste à élargir certaines parenthèses dans la contribution d'un programme, comme indiqué:

  1. Recherchez une chaîne s entre deux crochets correspondants [et ], avec un seul chiffre n après le crochet de fermeture.
  2. Retirez les crochets.
  3. Remplacez s par lui-même répété n fois. (Si n est 0, supprimez simplement s .)
  4. Passez à l'étape 1 jusqu'à ce qu'il n'y ait plus de crochets correspondants dans l'entrée.

Règles supplémentaires et clarifications:

  • Vous allez prendre une entrée et donner une sortie par tout moyen autorisé.
  • Un retour à la ligne final dans la sortie est autorisé.
  • Vous devez uniquement gérer l’ASCII imprimable dans l’entrée.
  • Vous pouvez supposer que tous les crochets correspondent, c'est-à-dire que vous ne recevrez jamais l'entrée []]]]ou [[[[].
  • Vous pouvez supposer que chaque parenthèse fermante ]est suivie d'un chiffre.

Cas de test:

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

S'agissant de , la réponse la plus courte dans chaque langue est gagnante. Bonne chance!

MD XF
la source
Poteau en sable .
MD XF
13
Vous devriez poster un autre défi pour compresser une chaîne dans son format le plus court
Jo King
Est-il utile d'indiquer explicitement que votre chaîne sne doit jamais contenir d'autres crochets? Par exemple, une tentative de résolution [Foo[Bar]3]2en développant la chaîne Foo[Bar3 fois entraînerait un état non valideFoo[BarFoo[BarFoo[Bar]2
BradC
@BradC, tout dépend de la manière dont vous choisissez d'implémenter la tâche.
MD XF
Cela signifie-t-il qu'il existe deux réponses valables à [a[b]2c[d]2e]2? Vous obtenez abbcddeabbcddeen développant bet en dpremier, mais ababcdbcdedbabcdbcdedeen développant a[bet en d]2epremier.
BradC

Réponses:

13

Gema , 17 caractères

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

Échantillon échantillon:

bash-4.4$ gema '[#]?=@repeat{?;#}' <<< '[three[two[one]1]2]3'
threetwoonetwoonethreetwoonetwoonethreetwoonetwoone
homme au travail
la source
Wow, parle de trouver la bonne langue pour le travail!
MD XF
Ou le bon travail pour la langue. De nombreux défis ont dû être ignorés car l'argument récursif n'était pas assez flexible.
Manatwork
Accepter cela pour l'instant parce que je ne vois aucun moyen de se faire battre, mais cela ne sera pas accepté dans le cas improbable où cela se produira.
MD XF
8

Retina , 24 23 22 octets

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

Essayez-le en ligne! Ceci est pratiquement intégré à Retina 1. Edit: 1 octet enregistré grâce à @Kobi. 47 45 octets dans la rétine 0.8.2:

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

Essayez-le en ligne!

Neil
la source
7

Haskell , 101 à 96 octets

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)

Essayez-le en ligne! Au lieu d'utiliser une expression régulière comme la plupart des autres réponses, cela implémente un analyseur récursif.

-5 octets grâce à BMO !

Laikoni
la source
4
Une déclaration de fixité pour (%)vous enregistre 1 octet et ['1'..d]vous en sauvegarde un autre 4, voir ceci .
ბიმო
3
@ BMO Nice, je ne m'attendais pas à ce qu'une déclaration de fixité soit utile pour le golf de code. Je pense que vous devriez ajouter cela à la question des conseils.
Laikoni
7

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

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

Essayez-le en ligne!

Réduisez-le avec l'aide de @Shaggy et @TonHospel.

Xcali
la source
3
Je ne connais pas la perle mais le refaire semble magnifique!
officialaimm
Je pense que vous devriez être capable de sauver un octet en évitant d'échapper à la ].
Shaggy
1
Je ne connais pas Perl mais cela semble fonctionner pour 30 + 1 octets.
Shaggy
2
Ces 29 + 1 fonctionnent également: perl -pe 's/.([^[]*?)](.)/$1x$2/e&&redo'etperl -pe 's/.([^][]*)](.)/$1x$2/e&&redo'
Ton Hospel le
5

Japt v2 , 21 20 19 octets

2 octets sauvés grâce à @Shaggy

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

Testez-le en ligne!

eis récursive replace, ce qui rend un remplacement à la fois jusqu'à ce qu'il n'y ait plus de correspondance. Dans ce cas, les correspondances de l'expression rationnelle /\[([^[]*?)](\d)/gsont remplacées par les fois <texte intérieur> répété <chiffre> jusqu'à ce qu'il n'y ait plus de correspondances.

Selon ce que j'ai prévu ( ici ), cette expression rationnelle devrait éventuellement être plus courte de 3 à 2 octets:

‹[“⁽[»₋”]“.›
ETHproductions
la source
2
Comme nous "pouvons supposer que chaque parenthèse fermante ]est suivie d’un chiffre ", vous devriez pouvoir la remplacer (\dpar (..
Shaggy
Vous pouvez également remplacer \[par.
Shaggy
@Shaggy Nice, merci!
ETHproductions
4

JavaScript, 71 67 66 octets

J'avais une solution de 54 octets , mais il foiré sur par suis le second cas de test! :(

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

Cas de test

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>

Hirsute
la source
4

Python 3 , 110 93 92 octets

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

Essayez-le en ligne!

-17 octets grâce à pizzapants184 -1 octet grâce à Kevin Cruijssen

Gábor Fekete
la source
1
-17 octets dans Python 3 avec indexation re.match et vérification de la sous-chaîne à l'aide de in.
pizzapants184
1
-1 octet en passant (\d)à (.), car nous savons qu'un crochet ]est toujours suivi d'un chiffre.
Kevin Cruijssen
4

Scala , 173 octets

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

Essayez-le en ligne!

Étendu:

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

Ancienne solution

Scala , 219 215 213 212 199 octets

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

Essayez-le en ligne!

Étendu:

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

Où l est la liste des chaînes que nous allons traiter.

Merci Kevin Cruijssen pour -1 octet

Nous sommes passés de 212 à 199 en supprimant un paramètre inutilisé, sans faire attention.

Shikkou
la source
4
Bienvenue chez PPCG! Essayez l'interprète scala de tio à tio.run/#scala et voyez si vous pouvez envoyer un lien pour obtenir la réponse, afin que d'autres puissent l'essayer en ligne. :)
officialaimm
2
Merci! J'ai édité la réponse pour inclure le lien. Espérons que la façon dont l’en-tête, le code et le pied de page sont déclarés est acceptable afin d’être une soumission correcte.
Shikkou
1
Bonjour, bienvenue sur PPCG! Super première réponse, +1 de moi. Je pense que vous pouvez économiser 1 octet en changeant (\d)sur (.), car nous savons qu'un accolade ]est toujours suivie d'un chiffre.
Kevin Cruijssen
3

Empilé , 39 38 octets

Sauvé 1 octet grâce à Shaggy, golfé la regex!

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

Essayez-le en ligne!

Remplace simplement de manière récursive une expression rationnelle '\[([^[\]]+)](.)'par la règle de répétition.

Conor O'Brien
la source
Je pense que vous pouvez économiser un octet en évitant d'échapper au dernier ].
Shaggy
3

Python 3, 155 148 101 97 octets

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

Essayez-le en ligne

Merci à HyperNeutrino et Mego pour -47 octets et user202729 pour -4 octets.

Manish Kundu
la source
Faites un one-liner pour économiser quelques octets: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 octets

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

Edit: regex mis à jour avec la recommandation de Shaggy

Fragment:

max890
la source
2
Bienvenue chez PPCG! Vous pouvez réduire ce nombre à 70 octets en modifiant votre RegEx.
Shaggy
Oui, 72 octets, évidemment, désolé; J'oubliais de compter le f=!
Shaggy
2

QuadR avec l' argument, 30 28 octets

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

Essayez-le en ligne!

\[[^[]+?]. remplacer "caractère [non- [bourré ]" par

¯2↓⍵M laisser tomber les deux derniers caractères du M atch ( « ]chiffre « )
1↓ laisser tomber le premier caractère ( » [»)
 enferment à traiter dans son ensemble
(... )⍴r Eshape à la longueur:
⌽⍵M inverser la M atch
 choisir la première (le chiffre)
 évaluer
ε nlist ( aplatir)

 répéter jusqu'à ce qu'il n'y ait plus de changements


La fonction APL Dyalog équivalente est de 47 octets:

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

Essayez-le en ligne!

Adam
la source
2

Java 8, 250 249 241 239 octets

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 octets grâce à @JonathanFrech (le code contient maintenant deux caractères ASCII non imprimables, qui peuvent être vus dans le lien TIO ci-dessous).

Soupir ... Java avec regex est tellement limité .. Je vais me citer une autre réponse ici:

Remplacer WWWWpar 222West facile en Java, mais avec 4Wpas .. Si seulement Java avait le moyen d’utiliser le groupe de capture regex pour quelque chose .. Obtenir la longueur avec "$1".length(), remplacer la correspondance par elle-même "$1".replace(...), convertir la correspondance en entier avec new Integer("$1"), ou utiliser Quelque chose de similaire à Retina (c'est-à s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))- dire ou JavaScript (c'est-à-dire s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))) serait mon numéro 1, ce que j'aimerais voir à l'avenir en Java pour que le codgolfing en profite.>.> rien avec le match capture-groupe ..
Citation d'ici.

Explication:

Essayez-le en ligne.

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
la source
1
Je pense que vous pouvez utiliser un caractère réellement ASCII bien que non imprimable pour économiser deux octets . (Votre solution prend vraiment 241 octets, 239 caractères.)
Jonathan Frech
@ JonathanFrech Merci! Je cherchais un caractère de 1 octet en dehors de la plage imprimable ASCII. N'a pas pensé à utiliser un non imprimable ..
Kevin Cruijssen
2

C, 407 368 octets

Merci à Jonathan Frech pour avoir économisé des octets.

golfé (fichier crochet.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;}

non golfé avec programme:

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

Compilé avec gcc 5.4.1, gcc bracket.c

Tsathoggua
la source
1
368 octets .
Jonathan Frech
387 avec l'inclusion nécessaire (pour realloc). Je ferai une mise à jour propre (avec la version sans golf) plus tard. Merci
Tsathoggua
Si vous utilisez GCC, je pense que le compilateur tentera de deviner la définition des deux mallocet realloc, y compris stdlib.hpar elle-même.
Jonathan Frech
Je ne savais pas ça. Fonctionnalité intéressante pour le golf de code. Merci.
Tsathoggua le
2

Rouge , 147 octets

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
]

J'ai commencé à apprendre le dialecte Red Parse hier seulement, alors je suis sûr que mon code peut encore être amélioré. Parse est incomparablement plus bavard que regex, mais il est très clair, flexible et lisible et peut être librement mélangé avec le reste de la langue rouge.

Essayez-le en ligne!

Galen Ivanov
la source
1

Gelée , 30 octets

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

Essayez-le en ligne!


Explication.


œṡ”]µḢ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.
utilisateur202729
la source
1

C, 381 octets

Version compacte:

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

Version complète:

#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
la source
3
Bienvenue chez PPCG!
Shaggy
1
Bienvenue sur le site! Notez que les soumissions C doivent être des programmes ou des fonctions complets, pas seulement des extraits.
MD XF
1

Python, 80 octets

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

Essayez-le en ligne!

s("[Foo[Bar]3]2")Convertis [Foo[Bar]3]2à ''+('Foo'+('Bar')*3+'')*2+''et évalue.

Ne réussit pas à saisir des guillemets (par exemple [']3)

Ugoren
la source
J'ai voté contre cette réponse, car la question nécessite la gestion de tout code ASCII imprimable en entrée, et cette réponse ne le fait pas. Prévenez-moi si vous corrigez le problème et je retirerai volontiers mon vote.
Caird coinheringaahing