Ekspansi Bracket!

36

Tantangan Anda adalah untuk memperluas beberapa tanda kurung di input program seperti yang ditunjukkan:

  1. Temukan string di antara dua tanda kurung yang cocok [dan ], dengan satu digit n setelah braket penutup.
  2. Lepaskan kurung.
  3. Ganti s dengan dirinya sendiri berulang kali n . (Jika n adalah 0, cukup hapus s .)
  4. Lanjutkan ke langkah 1 hingga tidak ada lagi tanda kurung yang cocok di input.

Aturan dan klarifikasi tambahan:

  • Anda akan mengambil input dan memberikan output melalui segala cara yang diizinkan.
  • Baris baru yang tertinggal di output diizinkan.
  • Anda hanya perlu menangani ASCII yang dapat dicetak dalam input.
  • Anda dapat berasumsi bahwa semua tanda kurung cocok, artinya Anda tidak akan pernah menerima input []]]]atau [[[[].
  • Anda dapat mengasumsikan bahwa setiap braket penutup ]memiliki angka setelahnya.

Kasus uji:

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

Karena ini adalah , jawaban terpendek dalam setiap bahasa menang. Semoga berhasil!

MD XF
sumber
13
Anda harus memposting tantangan lain untuk mengompresi string kembali ke format terpendek
Jo King
Apakah layak menyatakan secara eksplisit bahwa string Anda stidak boleh mengandung tanda kurung lain? Misalnya, mencoba menyelesaikan [Foo[Bar]3]2dengan memperluas string Foo[Bar3 kali akan menghasilkan keadaan yang tidak validFoo[BarFoo[BarFoo[Bar]2
BradC
@BradC semua tergantung pada bagaimana Anda memilih untuk mengimplementasikan tugas.
MD XF
Apakah itu berarti ada dua jawaban yang valid [a[b]2c[d]2e]2? Anda dapatkan abbcddeabbcddedengan memperluas bdan dpertama, tetapi ababcdbcdedbabcdbcdededengan memperluas a[bdan d]2epertama.
BradC

Jawaban:

13

Gema , 17 karakter

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

Contoh dijalankan:

bash-4.4$ gema '[#]?=@repeat{?;#}' <<< '[three[two[one]1]2]3'
threetwoonetwoonethreetwoonetwoonethreetwoonetwoone
manatwork
sumber
Wow, bicara tentang menemukan bahasa yang tepat untuk pekerjaan itu!
MD XF
Atau pekerjaan yang tepat untuk bahasa tersebut. Banyak tantangan harus dilewati karena argumen rekursif tidak cukup fleksibel.
manatwork
Menerima ini untuk saat ini karena saya tidak melihat ada cara mengalahkan, tetapi itu tidak akan diterima dalam kasus yang tidak mungkin terjadi.
MD XF
8

Retina , 24 23 22 byte

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

Cobalah online! Ini sebenarnya adalah builtin di Retina 1. Edit: Disimpan 1 byte berkat @Kobi. 47 45 byte di Retina 0.8.2:

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

Cobalah online!

Neil
sumber
7

Haskell , 101 96 byte

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)

Cobalah online! Alih-alih menggunakan ekspresi reguler seperti sebagian besar jawaban lainnya, ini mengimplementasikan pengurai rekursif.

-5 byte terima kasih kepada BMO !

Laikoni
sumber
4
Deklarasi fixity untuk (%)menghemat 1 byte dan ['1'..d]menghemat 4 byte lagi, lihat ini .
ბიმო
3
@BMO Bagus, saya tidak berharap deklarasi fixity akan berguna untuk kode golf. Saya pikir Anda harus menambahkan itu ke pertanyaan kiat.
Laikoni
7

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

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

Cobalah online!

Hentikan itu dengan bantuan dari @Shaggy dan @TonHospel.

Xcali
sumber
3
Saya tidak tahu mutiara tetapi mengulang tampaknya cantik!
officialaimm
Saya pikir Anda harus dapat menyimpan byte dengan tidak melarikan diri ].
Shaggy
1
Saya tidak tahu Perl tetapi ini tampaknya bekerja selama 30 + 1 byte.
Shaggy
2
29 +1 ini juga bekerja: perl -pe 's/.([^[]*?)](.)/$1x$2/e&&redo'danperl -pe 's/.([^][]*)](.)/$1x$2/e&&redo'
Ton Hospel
5

Japt v2 , 21 20 19 byte

Disimpan 2 byte berkat @Shaggy

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

Uji secara online!

eadalah penggantian rekursif, yang membuat penggantian satu per satu sampai tidak ada lagi yang cocok. Dalam hal ini, kecocokan dari regex /\[([^[]*?)](\d)/gdiganti dengan <teks dalam> diulangi <digit> sampai tidak ada lagi kecocokan.

Menurut apa yang telah saya rencanakan (di sini ), regex ini pada akhirnya harus setidaknya 3 2 byte lebih pendek:

‹[“⁽[»₋”]“.›
Produksi ETH
sumber
2
Karena kami " dapat berasumsi bahwa setiap braket penutup ]memiliki angka setelahnya " Anda harus dapat menggantinya (\ddengan (..
Shaggy
Anda juga dapat mengganti \[dengan.
Shaggy
@ Shaggy Nice, terima kasih!
Produk ETH
4

JavaScript, 71 67 66 byte

Saya punya solusi 54 byte tetapi gagal oleh test case kedua! :(

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

Uji Kasus

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>

Shaggy
sumber
4

Python 3 , 110 93 92 byte

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

Cobalah online!

-17 byte terima kasih kepada pizzapants184 -1 byte terima kasih kepada Kevin Cruijssen

Gábor Fekete
sumber
1
-17 byte dalam Python 3 dengan pengindeksan ulang dan pemeriksaan substring menggunakan in.
pizzapants184
1
-1 byte dengan mengubah (\d)ke (.), karena kita tahu blok-braket ]selalu diikuti oleh angka.
Kevin Cruijssen
4

Scala , 173 byte

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

Cobalah online!

Diperluas:

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

Solusi lama

Scala , 219 215 213 212 199 byte

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

Cobalah online!

Diperluas:

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

Di mana l adalah daftar string yang akan kami proses.

Terima kasih Kevin Cruijssen untuk -1 byte

Pergi dari 212 hingga 199 dengan menghapus parameter yang tidak digunakan, tidak memperhatikan.

Shikkou
sumber
4
Selamat datang di PPCG! Coba juru bahasa tio di tio.run/#scala dan lihat apakah Anda dapat mengirimkan tautan untuk jawabannya, sehingga orang lain dapat mencobanya secara online. :)
officialaimm
2
Terima kasih! Saya mengedit jawaban untuk menyertakan tautan. Semoga tidak masalah bagaimana header, kode, dan catatan kaki dideklarasikan untuk menjadi pengiriman yang tepat.
Shikkou
1
Hai, selamat datang di PPCG! Jawaban pertama yang bagus, +1 dari saya. Saya pikir Anda dapat menyimpan 1 byte dengan mengubah (\d)ke (.), karena kita tahu blok-braket ]selalu diikuti oleh digit.
Kevin Cruijssen
3

Ditumpuk , 39 38 byte

Disimpan 1 byte berkat Shaggy, golf regex!

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

Cobalah online!

Secara rekursif menggantikan regex '\[([^[\]]+)](.)'dengan aturan pengulangan.

Conor O'Brien
sumber
Saya pikir Anda dapat menyimpan byte dengan tidak melarikan diri dari yang terakhir ].
Shaggy
3

Python 3, 155 148 101 97 byte

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

Cobalah secara Online

Berkat HyperNeutrino dan Mego untuk -47 byte dan user202729 untuk -4 byte.

Manish Kundu
sumber
Buat satu-liner untuk menyimpan beberapa byte: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 byte

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

Sunting: regex yang diperbarui dengan rekomendasi Shaggy

Potongan:

maks890
sumber
2
Selamat datang di PPCG! Anda bisa mendapatkan ini hingga 70 byte dengan men-tweak RegEx Anda.
Shaggy
Ya, 72 byte, jelas, maaf; Saya lupa menghitung f=!
Shaggy
2

QuadR dengan argumen, 30 28 byte

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

Cobalah online!

\[[^[]+?]. ganti " karakter [non- [barang ]" dengan

¯2↓⍵M menjatuhkan dua karakter terakhir dari M atch ( " ]digit ')
1↓ menjatuhkan karakter pertama (' [")
 melampirkan diperlakukan secara keseluruhan
(... )⍴r eshape dengan panjang:
⌽⍵M membalikkan M atch
 memilih pertama (digit)
 mengevaluasi
ε nlist ( meratakan)

 ulangi sampai tidak ada lagi perubahan yang terjadi


Fungsi Dyalog APL yang setara adalah 47 byte:

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

Cobalah online!

Adm
sumber
2

Java 8, 250 249 241 239 byte

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 byte berkat @JonathanFrech (kode mengandung dua karakter ASCII yang tidak dapat dicetak sekarang, yang dapat dilihat pada tautan TIO di bawah).

Sigh ... Java dengan regex sangat terbatas .. Saya hanya akan mengutip sendiri dari jawaban lain di sini:

Mengganti WWWWdengan 222Wmudah di Jawa, tetapi dengan 4Wtidak .. Kalau saja Jawa memiliki cara untuk menggunakan regex capture-group untuk sesuatu .. Memperoleh panjang "$1".length(), mengganti pertandingan itu sendiri dengan "$1".replace(...), mengubah pertandingan itu menjadi bilangan bulat dengan new Integer("$1"), atau menggunakan sesuatu yang mirip dengan Retina (yaitu s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))atau JavaScript (yaitu s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))) akan menjadi hal nomor 1 saya yang ingin saya lihat di Jawa di masa depan untuk mendapatkan keuntungan codegolfing ..>.> Saya pikir ini adalah kali ke 10 + saya benci Java tidak bisa melakukan apa saja dengan pertandingan grup tangkap ..
Kutip dari sini.

Penjelasan:

Cobalah 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
sumber
1
Saya pikir Anda dapat menggunakan karakter yang benar-benar ASCII meskipun tidak patut untuk menghemat dua byte . (Solusi Anda benar-benar membutuhkan 241 byte, 239 karakter.)
Jonathan Frech
@JonathanFrech Terima kasih! Sedang mencari karakter 1-byte di luar rentang ASCII yang dapat dicetak. Tidak terpikir untuk menggunakan yang tidak patut ..
Kevin Cruijssen
2

C, 407 368 byte

Terima kasih kepada Jonathan Frech untuk menghemat byte.

golf (braket file.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 dengan program:

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

Dikompilasi dengan gcc 5.4.1, gcc bracket.c

Tsathoggua
sumber
1
368 byte .
Jonathan Frech
387 dengan yang diperlukan meliputi (untuk realokasi). Saya akan melakukan pembaruan bersih (dengan versi yang tidak ungolfed) nanti. Terima kasih
Tsathoggua
Jika Anda menggunakan GCC, saya pikir kompiler akan mencoba menebak definisi keduanya mallocdan realloc, termasuk stdlib.holehnya sendiri.
Jonathan Frech
Saya tidak tahu itu. Fitur bagus untuk bermain golf kode. Terima kasih.
Tsathoggua
2

Merah , 147 byte

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]

Tidak Disatukan:

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
]

Saya mulai belajar dialek Red's Parse hanya kemarin, jadi saya yakin kode saya dapat ditingkatkan lebih lanjut. Parse jauh lebih verbose daripada regex, tetapi sangat jelas, fleksibel dan mudah dibaca dan dapat dicampur secara bebas dengan sisa bahasa Merah.

Cobalah online!

Galen Ivanov
sumber
1

Jelly , 30 byte

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

Cobalah online!


Penjelasan.


œṡ”]µḢ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.
pengguna202729
sumber
1

C, 381 byte

Versi ringkas:

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

Versi lengkap:

#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
sumber
3
Selamat datang di PPCG!
Shaggy
1
Selamat datang di situs ini! Perhatikan bahwa pengiriman C harus berupa program atau fungsi lengkap, bukan hanya cuplikan.
MD XF
1

Python, 80 byte

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

Cobalah online!

s("[Foo[Bar]3]2")Konversi [Foo[Bar]3]2ke ''+('Foo'+('Bar')*3+'')*2+'', dan mengevaluasi.

Gagal untuk input dengan kutipan dalam tanda kurung (mis. [']3)

ugoren
sumber
Saya menurunkan jawaban ini karena pertanyaannya memerlukan penanganan ASCII yang dapat dicetak dalam input, dan jawaban ini tidak. Beri tahu saya jika Anda memperbaikinya, dan saya akan dengan senang hati menarik kembali suara saya.
caird coinheringaahing