ブラケット拡張!


36

あなたの挑戦は、示されているようにプログラムの入力でいくつかの括弧を拡張することです:

  1. 2つの一致する角かっこと間の文字列sを見つけます。閉じ角かっこの後に1桁のnが付きます。[]
  2. ブラケットを取り外します。
  3. sをそれ自体でn回繰り返して置き換えます。(nが0の場合、単にsを削除します。)
  4. 入力に一致する括弧がなくなるまで手順1に進みます。

追加の規則と説明:

  • 入力を受け取り、許可された手段で出力を行います。
  • 出力の末尾の改行が許可されます。
  • 入力で印刷可能なASCIIのみを処理する必要があります。
  • すべての括弧が一致する、つまり、入力[]]]]またはを受け取らないことを前提とする場合があります[[[[]
  • 各閉じ括弧の]後に数字があると仮定できます。

テストケース:

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

これはであるため、各言語の最短回答が勝ちます。がんばろう!



13
あなたは、その最短形式に至るまでの文字列バックを圧縮する別の挑戦を投稿する必要があります
ジョー・キング

あなたの文字列にs他の括弧が含まれてはならないことを明示的に述べる価値はありますか?たとえば[Foo[Bar]3]2、文字列をFoo[Bar3回展開して解決しようとすると、無効な状態になりますFoo[BarFoo[BarFoo[Bar]2
-BradC

@BradCはすべて、タスクの実装方法に依存します。
MD XF

それは、2つの有効な答えがあるということ[a[b]2c[d]2e]2ですか?あなたが得るabbcddeabbcdde拡大することによりb、およびd、最初ますがababcdbcdedbabcdbcdede拡大することによりa[b、およびd]2e最初。
BradC

回答:


13

Gema、17文字

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

サンプル実行:

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

仕事にふさわしい言語を見つけることについて話してください!
MD XF

または言語の適切な仕事。再帰的な議論には十分な柔軟性がないため、多くの課題をスキップする必要がありました。
マナトワーク

今のところこれを受け入れると、勝つ方法がわかりませんが、ありそうもないケースでは受け入れられません。
MD XF


7

Haskell101 96バイト

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)

オンラインでお試しください!他のほとんどの答えのような正規表現を使用する代わりに、これは再帰的なパーサーを実装します。

BMOのおかげで-5バイト!


4
以下のための固定性宣言は(%)、あなたに1つのバイトを保存し、['1'..d]あなたに別の4を保存し、参照これを
1

3
@BMOニース、フィクスティティー宣言がコードゴルフに役立つとは思っていませんでした。ヒントの質問にそれを追加すべきだと思います。
ライコニ

7

Perl 5の34 33 29 + 1(-p)= 30バイト

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

オンラインでお試しください!

@Shaggyと@TonHospelの助けを借りて削減してください。


3
私は真珠を知りませんが、やり直しは素晴らしいようです!
officialaimm

をエスケープしないことでバイトを節約できるはず]です。
シャギー

1
Perlはわかりませんが、これ 30 + 1バイトで動作するようです。
シャギー

2
これらも29 + 1作品:perl -pe 's/.([^[]*?)](.)/$1x$2/e&&redo'perl -pe 's/.([^][]*)](.)/$1x$2/e&&redo'
トンHospel

5

JAPT V221の 20 19バイト

@Shaggyのおかげで2バイト節約

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

オンラインでテストしてください!

e再帰的な置換であり、一致するものがなくなるまで一度に1つの置換を行います。この場合、正規表現の一致は、一致/\[([^[]*?)](\d)/gがなくなるまで<inner text>で<digit>回繰り返されます。

私が計画したもの(ここ)によれば、この正規表現は最終的に少なくとも3 2バイト短くなります:

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

2
私たちは「として、各閉じ括弧があることを前提とする]ことの後に数字を持っている」あなたは置き換えることができるはず(\d(.
シャギー

また、置き換えることができ\[.
シャギー

@Shaggy Nice、ありがとう!
ETHproductions

4

JavaScript、71 67 66バイト

54バイトのソリューションを持っていましたが、2番目のテストケースでめちゃくちゃになりました!:(

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

テストケース

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

Pythonの3110の 93 92バイト

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

オンラインでお試しください!

pizzapantsによる-17バイトのおかげ184 Kevin Cruijssenによる-1バイトのおかげ


1
Python 3-17バイト。re.matchインデックス付けとを使用しinた部分文字列チェック。
pizzapants184

1
ブロックブラケットの後には常に数字が続くため、-1に変更(\d)してに変更します。(.)]
ケビンクルーッセン

4

Scala、173バイト

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

オンラインでお試しください!

拡張:

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

古いソリューション

スカラ座219の 215 213 212 199バイト

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

オンラインでお試しください!

拡張:

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

ここで、lは処理する文字列のリストです。

-1バイトをありがとう、Kevin Cruijssen

未使用のパラメーターを削除して212から199に移動しましたが、注意を払っていませんでした。


4
PPCGへようこそ!tio.run/#scalaでtioのscalaインタープリターを試し、他の人がオンラインで試せるように、回答のリンクを送信できるかどうかを確認してください。:)
officialaimm

2
ありがとうございました!回答を編集してリンクを含めました。ヘッダー、コード、およびフッターを適切に送信するためにどのように宣言するかは問題ないでしょう。
-Shikkou

1
こんにちは、PPCGへようこそ!すばらしい最初の答え、私からの+1。ブロックブラケットの後に常に数字が続くことがわかっているため、に変更(\d)する(.)と1バイト節約できると思います]
ケビンクルーイッセン


3

Python 3、155 148 101 97バイト

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

オンラインで試す

-47バイトのHyperNeutrinoとMego、-4バイトのuser202729に感謝します。


数バイトを節約するためにワンライナーにします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バイト

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

編集:シャギーの推奨で正規表現を更新

スニペット:


2
PPCGへようこそ!RegExを微調整することで、これを70バイトまで減らすことができます。
シャギー

はい、72バイト、明らかに申し訳ありません。数えるのを忘れていたf=
シャギー

2

引数付きのQuadR30 28バイト

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

オンラインでお試しください!

\[[^[]+?]. 「[[スタッフ]文字」を置き換えます

¯2↓⍵M 最後の2つの文字ドロップMの ATCHは(「]数字『)
1↓ 最初の文字(』ドロップ[」)
 、全体として扱われることを囲む
(... )⍴のR:長さにeshape
⌽⍵M 逆Mの ATCHは
 (数字)最初に選ん
 評価
ε(NLISTを平坦化)

 変化がなくなるまで繰り返します


同等のDyalog APL関数は47バイトです:

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

オンラインでお試しください!


2

Javaの8、250の 249 241 239バイト

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

@JonathanFrechのおかげで-2バイト(コードには現在2つの印刷できないASCII文字が含まれています。これは以下のTIOリンクで確認できます)。

ため息...正規表現を使用したJavaは非常に限られています。ここで別の答えから引用します。

交換WWWWでは、222WJavaで簡単ですが、と4Wはない...唯一のJavaは何かのために正規表現のキャプチャグループを使用する方法..と長さを取得していた場合"$1".length()、との試合自体を交換する"$1".replace(...)、と整数に試合を変換するnew Integer("$1")、または使用をRetinaに似たもの(つまりs.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))、JavaScript(つまりs.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))))は、コードゴルフの利益のために将来Javaで見たい私のナンバー1のものです。>。> Javaが嫌いなのは10回目だと思いますキャプチャグループが一致するものはすべて
ここから引用します。

説明:

オンラインでお試しください。

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
2バイトを節約するために、印刷できない文字であるにもかかわらず、本当にASCIIを使用できると思います。(あなたのソリューションは本当に241バイト、239文字かかります。)
ジョナサンフレッチ

@JonathanFrechありがとう!印刷可能なASCII範囲外の1バイト文字を探していました。...印刷できないを使用してについて考えていなかった
ケビンCruijssen


2

C、407 368バイト

バイトを節約してくれたJonathan Frechに感謝します。

ゴルフ(ファイルbracket.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;}

プログラムを使用しない:

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

gcc 5.4.1でコンパイル、 gcc bracket.c



必要なincludeを含む387(realloc用)。後からクリーンな更新を行います(変更されていないバージョンで)。ありがとう
-Tsathoggua

あなたはGCCを使用している場合、私は、コンパイラは、両方の定義を推測しようとすると思うmallocreallocを含む、stdlib.h自身のことで。
ジョナサンフレッチ

知りませんでした。コードゴルフの素晴らしい機能。ありがとう。
ツァソググア

2

、147バイト

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]

ゴルフをしていない:

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
]

RedのParse方言を学習したのは昨日だけだったので、コードをさらに改善できると確信しています。解析は正規表現よりも比較にならないほど冗長ですが、非常に明確で柔軟で読みやすく、他のRed言語と自由に混在させることができます。

オンラインでお試しください!


1

ゼリー、30バイト

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

オンラインでお試しください!


説明。


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

コンパクトバージョン:

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

完全版:

#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
PPCGへようこそ!
シャギー

1
サイトへようこそ!Cの送信は、スニペットだけでなく、完全なプログラムまたは機能である必要があることに注意してください。
MD XF

1

Python、80バイト

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

オンラインでお試しください!

s("[Foo[Bar]3]2")変換[Foo[Bar]3]2''+('Foo'+('Bar')*3+'')*2+''、評価します。

括弧内の引用符での入力に失敗します(例[']3


質問は入力で印刷可能なASCIIを処理する必要があるので、この答えはダウンボットしましたが、この答えはそうではありません。修正したら通知してください。投票を取り消します。
コイナーリンガーを育てる
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.