브라켓 확장!


36

다음과 같이 프로그램 입력에서 일부 괄호를 확장해야합니다.

  1. 문자열 찾기 들 이 일치하는 괄호 [와 ]한 자리에, N 닫기 괄호 후.
  2. 브래킷을 제거하십시오.
  3. 대체 들 자체가 반복 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
문자열을 가장 짧은 형식으로 다시 압축해야하는 또 다른 과제를 게시해야합니다.
— Jo King

문자열에 s다른 대괄호가 포함되어서는 안된다고 명시 적으로 언급 할 가치가 있습니까? 예를 들어, [Foo[Bar]3]2문자열을 Foo[Bar3 번 확장하여 풀려고 하면 잘못된 상태가됩니다.Foo[BarFoo[BarFoo[Bar]2
— BradC

@BradC는 모두 작업 구현을 선택하는 방법에 달려 있습니다.
— MD XF

그것은 두 가지 유효한 답변이 있다는 것을 의미합니까 [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

또는 언어에 맞는 직업. 재귀 주장이 충분히 유연하지 않았기 때문에 많은 과제를 건너 뛰어야했습니다.
— manatwork

지금 당장 이걸 받아들이면 이길 방법이 보이지 않지만, 그렇지 않을 경우에는 받아 들여지지 않을 것입니다.
— MD XF


7

하스켈 , 101 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를 저장, 볼 이 .
— ბიმო

3
@ BMO 니스, 고 정성 선언이 코드 골프에 유용 할 것이라고 기대하지 않았습니다. 팁 질문에 추가해야한다고 생각합니다.
— Laikoni

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 v2 , 21 20 19 바이트

@Shaggy 덕분에 2 바이트 절약

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

온라인으로 테스트하십시오!

e재귀 교체로 일치하는 항목이 더 이상 없을 때까지 한 번에 하나씩 교체합니다. 이 경우 정규식과 일치/\[([^[]*?)](\d)/g 일치 항목은 더 이상 일치하지 않을 때까지 <숫자> 번 반복되는 <내부 텍스트>로 바뀝니다.

내가 계획 한 것에 따르면 ( here ),이 정규식은 결국 3 2 바이트 더 짧아야합니다.

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

2
로서 우리는 " 각 닫는 대괄호가 있다고 가정 할 수 ]는 후 숫자가 바꿀 수있을 것" (\d으로를 (..
— 얽히고 설킨

또한 대체 할 수 \[와.
— 얽히고 설킨

@Shaggy Nice, 감사합니다!
— ETHproductions

4

자바 스크립트, 71 67 66 바이트

나는 한 54 바이트 솔루션을 있지만 두 번째 테스트 케이스가 이상 나사있어! :(

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

파이썬 3 , 110 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
를 사용하여 re.match 인덱싱 및 하위 문자열 검사를 사용하여 Python 3에서 -17 바이트in .
— pizzapants184

1
변경하여 -1 바이트 (\d)에 (.)우리가 블록 브래킷을 알고 있기 때문에이 ]항상 자리옵니다.
— Kevin Cruijssen

4

스칼라 , 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의 스칼라 통역사를 사용 해보고 다른 사람들이 온라인으로 시도 할 수 있도록 답변에 대한 링크를 제출할 수 있는지 확인하십시오. :)
— officialaimm

2
감사합니다! 링크를 포함하도록 답변을 편집했습니다. 제대로 제출하기 위해 머리글, 코드 및 바닥 글이 어떻게 선언되어 있는지 확인하십시오.
— Shikkou

1
안녕하세요, PPCG에 오신 것을 환영합니다! 첫 번째 대답은 +1입니다. 블록 브래킷 뒤에 항상 숫자가 있기 때문에 로 변경 (\d)하여 1 바이트를 절약 할 수 있다고 생각합니다 . (.)]
— Kevin Cruijssen


3

파이썬 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

자바 스크립트 - 77 75 72 바이트

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

편집 : Shaggy의 권장 사항으로 정규식을 업데이트했습니다.

단편:


2
PPCG에 오신 것을 환영합니다! RegEx를 조정하여 70 바이트 로 줄일 수 있습니다 .
— 얽히고 설킨

네, 분명히 72 바이트입니다. 죄송합니다. 나는 계산하는 것을 잊고 있었다 f=!
— 얽히고 설킨

2

인수가 있는 QuadR≡ , 30 28 바이트

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

온라인으로 사용해보십시오!

\[[^[]+?]. " [non- [stuff ]character"로 바꾸십시오

¯2↓⍵M 의 마지막 두 문자 드롭 M의 ATCH ( " ]숫자")
1↓ ( "첫 번째 문자를 드롭을 [")
⊂ 묶으이 전체로 취급하는
(... )⍴ r에 : 길이 eshape
 ⌽⍵M 역 M의 ATCH가
 ⊃ 첫 번째 (숫자를) 선택
 ⍎ 평가
∊ ε (NLIST를 반음 낮추다)

≡ 더 이상 변화가 없을 때까지 반복


동등한 Dyalog APL 함수는 47 바이트입니다.

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

온라인으로 사용해보십시오!


2

자바 (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 바이트 (코드에는 인쇄 할 수없는 두 개의 ASCII 문자가 포함되어 있으며 아래 TIO 링크에서 볼 수 있음)

한숨 .. 정규 표현식을 사용하는 Java는 너무 제한적입니다. 여기에 또 다른 대답에서 인용하겠습니다.

Java로 대체 WWWW하는 222W것은 쉽지만 그렇지는 4W않습니다. Java에서만 정규 표현식 캡처 그룹을 사용하는 방법이 있다면.로 길이를 "$1".length()얻거나으로 일치를 바꾸 "$1".replace(...)거나을 사용하여 일치를 정수로 변환 new Integer("$1")하거나 Retina와 비슷한 것 (즉 s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1")), JavaScript (ie 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
인쇄 할 수없는 문자이지만 ASCII를 사용하여 2 바이트 를 절약 할 수 있다고 생각합니다 . (솔루션은 실제로 241 바이트, 239 자입니다.)
— Jonathan Frech

@JonathanFrech 감사합니다! 인쇄 가능한 ASCII 범위를 벗어난 1 바이트 문자를 찾고있었습니다. 인쇄 할 수없는 사용에 대한 생각하지 않았나요 ..
— 케빈 Cruijssen에게


2

C, 407 368 바이트

바이트를 절약 해 준 Jonathan Frech에게 감사합니다.

골프 (파일 브래킷 .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



387에 필요한 포함 (realloc의 경우)이 포함됩니다. 나중에 업데이트되지 않은 버전으로 업데이트합니다. 감사합니다
— Tsathoggua

GCC를 사용한다면 컴파일러가 malloc와 realloc를 포함한 정의를 추측하려고 시도합니다 stdlib.h.
— Jonathan Frech

나는 몰랐다. 코드 골프를위한 멋진 기능. 감사.
— Tsathoggua

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 's Parse dialect를 배우기 시작했기 때문에 코드를 더 향상시킬 수 있다고 확신합니다. 구문 분석은 정규식보다 비교할 수 없을 정도로 장황하지만, 매우 명확하고 유연하며 읽기 쉽고 나머지 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

파이썬, 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를 처리해야하기 때문에이 답변을 하향 투표했지만이 답변은 그렇지 않습니다. 문제를 해결하면 알려 주시면 기꺼이 투표권을 철회하겠습니다.
— caird coinheringaahing
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.