브라켓 확장!


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[bd]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를 사용한다면 컴파일러가 mallocrealloc를 포함한 정의를 추측하려고 시도합니다 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.