支架扩展!


36

您面临的挑战是在程序的输入中扩展一些括号,如下所示:

  1. 在两个匹配的括号和之间找到一个字符串s,在括号后面加上一个数字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
您应该发布另一个挑战,将字符串压缩回最短格式
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通过扩展bd第一来获得,但是ababcdbcdedbabcdbcdede通过扩展a[bd]2e第一可以得到。
BradC

Answers:


13

杰玛(Gema),17个字符

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

样品运行:

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

哇,说说为工作找到合适的语言!
MD XF

还是适合该语言的工作。由于递归参数不够灵活,因此不得不跳过许多挑战。
manatwork '18

现在接受此操作,因为我看不到它被击败的任何方式,但是在不太可能的情况下,它不会被接受。
MD XF

8

视网膜24 23 22字节

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

在线尝试!这实际上是Retina 1中的内置函数。编辑:感谢@Kobi,节省了1个字节。Retina 0.8.2中的47个 45字节:

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

在线尝试!


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)

在线尝试!而不是像其他大多数答案一样使用正则表达式,而是实现了递归解析器。

-5字节感谢BMO


4
的固定性声明为(%)您节省了1个字节,为您['1'..d]节省了另外4 个字节,请参见this
ბიმო

3
@BMO很好,我没想到固定声明对代码打高尔夫球不会有用。我认为您应该将其添加到提示问题中。
Laikoni '18

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'
Ton Hospel '18年

5

Japt V221 20 19个字节

@Shaggy节省了2个字节

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

在线测试!

e是递归替换,它将一次替换一次,直到没有更多匹配为止。在这种情况下,将正则表达式的匹配项/\[([^[]*?)](\d)/g替换为<inner text>重复的<digit>次,直到不再匹配为止。

根据我的计划(在此处),此正则表达式最终应至少短3 2字节:

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

2
正如我们“ 可以假设每个右括号]有它后一个数字 ”,你应该能够取代(\d(.
粗野的

您也可以替换\[.
Shaggy

@Shaggy Nice,谢谢!
ETHproductions

4

JavaScript,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

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是我们将处理的字符串列表。

感谢Kevin Cruijssen -1个字节

通过删除未使用的参数从212转到199,没有引起注意。


4
欢迎来到PPCG!在tio.run/#scala上尝试tio的scala解释器,看看是否可以提交答案的链接,以便其他人可以在线尝试。:)
Officialaimm

2
谢谢!我编辑了答案以包含链接。希望如何声明页眉,代码和页脚以便正确提交。
Shikkou

1
嗨,欢迎来到PPCG!很棒的第一答案,来自我+1。我认为您可以通过更改(\d)为来节省1个字节(.),因为我们知道一个大括号后]总是跟一个数字。
凯文·克鲁伊森

3

堆叠39 38字节

感谢Shaggy节省了1个字节,让正则表达式打高尔夫球!

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

在线尝试!

只需'\[([^[\]]+)](.)'用重复规则递归地替换正则表达式即可。


我认为您可以通过不转义最后一个来节省一个字节]
毛茸茸的

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

编辑:更新的正则表达式与Shaggy的推荐

片段:


2
欢迎来到PPCG!您可以通过调整RegEx 将其减少到70个字节
粗野的

是的,显然是72个字节,很抱歉;我忘了数f=
毛茸茸的

2

参数的QuadR30个 28字节

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

在线尝试!

\[[^[]+?]. 将“ [[填充]字符”替换为

¯2↓⍵M 掉落的最后两个字符中号 ATCH(“ ]数字‘)
1↓ 下降的第一个字符(’ [”)
 的封装被处理作为一个整体
(... )⍴ř ESHAPE到长度:
⌽⍵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太受限制了。

更换WWWW222W很容易在Java中,但4W不..如果只有Java的有办法使用正则表达式捕获组东西..掌握的长度"$1".length(),以更换比赛本身"$1".replace(...),与之相匹配的,转换成整数new Integer("$1"),或者使用我希望将来能在Java中看到与Retina(即s.replaceAll("(?=(.)\\1)(\\1)+","$#2$1"))JavaScript(即s.replaceAll("(.)\\1+",m->m.length()+m.charAt(0))))类似的第一件事,以使代码高尔夫受益。>>我认为这是我讨厌Java第十次以上了与捕获组匹配的任何内容

说明:

在线尝试。

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字符(尽管无法打印)来节省两个字节。(您的解决方案实际上需要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,其中包含所需的内容(用于重新分配)。稍后,我将进行干净的更新(使用非高尔夫版本)。谢谢
Tsathoggua '18

如果您使用GCC,我认为编译器将尝试猜测mallocand 的定义realloc,包括stdlib.h它自己的定义。
Jonathan Frech '18

我不知道 代码打高尔夫球的不错功能。谢谢。
Tsathoggua '18

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,而这个答案不需要。如果您解决此问题,请通知我,我会很乐意收回我的投票。
Caird coinheringaahing
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.