生成所有长度为n的大括号


16

大括号字符串定义为由*()[]大括号正确匹配的字符组成的字符串:

[brace-string] ::= [unit] || [unit] [brace-string]
[unit]         ::= "" || "*" || "(" [brace-string] ")" || "[" [brace-string] "]"

这是一个有效的大括号字符串:

((())***[]**)****[(())*]*

但是这些不是:

)(
**(**[*](**)
**([*)]**

您的任务是编写一个程序(或函数),给定一个正整数n,该程序将一个数字作为输入并输出(或返回)所有有效的length括号n

技术指标

  • 您可以按任何顺序输出字符串。
  • 您可以将其输出为列表或由不同字符分隔的字符串。
  • 您的程序必须正确处理0。可能有1个长度为0的大括号字符串,即空字符串""
  • 这是,因此以字节为单位的最短有效答案为准。

测试用例

0. 
1. *
2. ** () []
3. *** ()* []* (*) [*] *() *[]
4. **** ()** []** (*)* [*]* (**) **() **[] *(*) *[*] (()) ()() ()[] ([]) [**] [()] [[]] []() [][] *()* *[]*

3
输出中的条目数为A025235-
加布里埃尔·贝纳米

@GabrielBenamy啊。我想知道以前是否曾经看过。有趣。
硕果累累

2
获奖条件是什么?我假设最短的程序(代码高尔夫球)。
Zgarb '16


1
由于每个人都认为这是代码高尔夫,因此我将相应地标记挑战(否则将使所有现有答案变得毫无意义)。如果您打算采用其他获胜标准,则可以考虑发布新挑战。
马丁·恩德

Answers:


3

果冻,29个字节

-3个字节,感谢@JonathanAllan

如果有任何问题/错误/错误或字节,提醒我!

“[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐLÐḟ

在线尝试!

我以前使用的解决方案:

“[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€Tị
“[(*)]”ṗµ¹ḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€Tị
“[(*)]”ṗµ¹ḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€×Jḟ0ị
“[(*)]”x⁸ṗ⁸Qµ¹ḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€×Jḟ0ị
“[(*)]”x⁸ṗ⁸Qµ¹µḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€×Jḟ0ị
“[(*)]”x⁸ṗ⁸Qµ¹µḟ”*œṣ⁾()Fœṣ⁾[]FµÐLµ€Ṇ€×Jḟ0ị

说明(我尽力描述):

Input n
“[(*)]”ṗ-All strings composed of "[(*)]" of length n
µḟ”*    -Filter out all occurences of "*"
œṣ⁾()   -Split at all occurences of "()"
F       -Flatten
œṣ⁾[]   -Split at all occurences of "[]"
F       -Flatten
µÐL     -Repeat that operation until it gives a duplicate result
Ðḟ      -Filter

您可以使用过滤(“[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐLÐḟ)保存三个字节
Jonathan Allan

15

Prolog,69个字节

s-->[];e,s.
e-->"*";"(",s,")";"[",s,"]".
b(N,A):-length(A,N),s(A,[]).

Prolog最有趣的特性之一是,在许多情况下,它能够向后运行程序。例如,您可以生成真实的所有解决方案,而不是测试是否真实,而无需检查字符串的长度,而可以生成具有给定长度的所有字符串。(Prolog的另一个不错的特性是,在每个谓词定义的末尾都需要空格,并且可以像空间一样便宜地插入换行符;因此,即使是打高尔夫球的程序也通常可读性强。)

上面定义了一个谓词(一个函数的等效项)b,该谓词进行测试以查看字符串是否具有给定的长度,并且是问题中定义的“大括号字符串”。具体来说,它是通过Prolog的grammar / regex / pattern-match支持来实现的,该支持为定义此类表达提供了一些不错的简短提示(显然,这是标准/可移植的,但是我在最初编写答案时并没有意识到这一点,因此假设答案仅适用于一个Prolog实施;不过,似乎它适用于符合标准的每个实施。该程序可以直接翻译成英文。前两行说“一个s是一个空字符串,或者一个e后跟一个s;一个e是星号,括号中是s,或方括号中是s。”第三行可以解释为“ 如果A是长度为N的列表,并且As后跟null ,则Nb可以是A串。”

我要加倍小心地编写s(并因此b),以便它们以一种唯一的方式匹配每个“括号字符串”(这是两者se必须存在的原因,而不是将它们分组为一个谓词)。这使得它们完全可逆。因此b,除了测试字符串是否为给定长度的括号字符串外,还可以用于生成给定长度的所有“括号字符串”(也可以在第三回合中使用它来计算括号的长度)字符串,但这几乎可以肯定是它最不实用的操作模式)。实施是递归的,例如,以产生一个小号,代码将产生所有可能的Ë不再比输出的所需长度s和追加的所有可能的小号适合剩余空间的 因为我预先指定了参数的长度(在b内),所以Prolog引擎知道它无法生成比给定长度更长的输出,从而可以终止递归。

这是正在运行的程序的示例:

| ?- b(4,A),format("~s ",[A]),fail.
**** **() **[] *()* *(*) *[]* *[*] ()** ()() ()[] (*)* (**) (()) ([]) []** []() [][] [*]* [**] [()] [[]]

感觉要指定是要“向前”还是“向后”运行该程序所需的语法应该有所花费。perl为这种事情的每一位支付1个字节
Sparr

好吧,您可以制定一条规则,使末尾的参数始终是返回值,然后反转参数的顺序以指定运行程序的方式。打高尔夫球的语言通过查看是否得到任何输入来弄清楚他们应该做什么,这是相当普遍的,这是一个可比的原则。但是,总的来说,很难制定适用于每种可能语言的规则。运行像建宏lengthappend方式轮要么是语言的基本组成部分,以及用户函数通常这样做。

哦,嗯。我认为您的示例中有某种迹象触发了有问题的行为。
Sparr

不,这完全是由于给出了哪些参数。在上面的程序中,我写了length(A,N);如果N给定和A不提供(如果谓词以程序中请求的方式使用,则会发生),length它将生成一个AN未知元素组成的列表。使用length测量列表的长度可能是较为常用的(虽然使用它“倒退”,是相当常见的Prolog中编程)。大多数谓词最终的工作方式几乎相同(它们唯一不这样做的原因是,如果尝试将它们取反会构造一个无限循环,这是相当普遍的)。

1
@ ais523 -->和DCG通常是标准的ISO Prolog
致命

5

Haskell,101 94字节

Zgarb保存了7个字节!

b 0=[""]
b n=[x++y|k<-[1..n],x<-u k,y<-b$n-k]
u 1=["*"]
u n=[a:s++b|s<-b$n-2,a:b<-["()","[]"]]

遵循定义几乎是直接的,但是""情况有所变化。

采用:

*Main> map b [0..3]
[[""],["*"],["**","()","[]"],["***","*()","*[]","()*","[]*","(*)","[*]"]]
*Main> length $ b 10
21595

(在慢速计算机上,第二次计算花费的时间少于一秒钟。)

我还想分享我在考虑生成函数时想到的另一种方法的结果。它定义了一个列表 b的字符串,使得列表b!!n包含了长度的所有支柱串n。同样,u!!n包含所有大小为的原子n-1。一件好事是代码没有使用任何数字。它不完全golfed:ui会内联,它肯定会缺少一些其他高尔夫的机会。不幸的是,它看起来并不比第一个版本短,但它的计算length $ b !! 10速度甚至更快。

b=[""]:b%u
u=["*"]:map i b
i=concatMap(\s->['(':s++")",'[':s++"]"])
(b:c)%f=zipWith(++)[[x++y|x<-b,y<-e]|e<-f]([]:c%f)

使用b$n-k和保存两个字节b$n-2。另外,在最后一行您可以执行a:b<-["()","[]"]并返回a:s++b
Zgarb '16

哦,我想使用,["()","[]"]但看不到如何使用它来提高代码大小。谢谢!
Christian Sievers,2016年

4

Mathematica,116个字节

#<>""&/@Select[Characters@"*([)]"~Tuples~#,(#/."*"->Nothing//.{a___,"(",")",b___}|{a___,"[","]",b___}:>{a,b})=={}&]&

说明

Characters@"*([)]"

找到字符串的字符"*([)]",给出List {"*", "(", "[", ")", "]"}

... ~Tuples~#

找到上述列表中具有length的元组n

(#/."*"->Nothing//.{a___,"(",")",b___}|{a___,"[","]",b___}:>{a,b})=={}&

未命名的布尔函数,用于查找元组是否平衡:

#/."*"->Nothing

删除"*"输入中的所有内容。

... //.{a___,"(",")",b___}|{a___,"[","]",b___}:>{a,b}

重复删除"("")""["和的所有连续出现,"]"直到输入不变。

... =={}

检查结果是否为空List

Select[ ... , ... ]

查找True应用布尔函数时给出的元组。

#<>""&/@

将每个List字符转换为Strings。


2
出乎意料的是,{x=a___,"(",")",y=b___}|{x,"[","]",y}似乎可行。
马丁·恩德

4

Python 2,128字节

n=input()
for i in range(5**n):
 try:s=','.join('  "00([*])00"  '[i/5**j%5::5]for j in range(n));eval(s);print s[1::4]
 except:1

螺丝递归正则表达式–我们正在使用Python的解析器!为了验证例如*(**[])*是否为大括号字符串,我们执行以下操作:

  1. 创建一个类似的字符串"*", (0,"*","*", [0,0] ,0) ,"*",其中每个第二个字符(四个字符)是大括号字符串中的一个字符,其余字符粘合在一起,使其成为潜在的Python表达式。

  2. eval 它。

  3. 如果那没有引发错误,请打印s[1::4](大括号字符)。

选择粘合字符,以便当且仅当每四个字符中的第二个字符产生一个有效的大括号字符串时,我创建的字符串才是有效的Python表达式。


2

PHP,149字节

for(;$argv[1]--;$l=$c,$c=[])foreach($l?:['']as$s)for($n=5;$n--;)$c[]=$s.'*()[]'[$n];echo join(' ',preg_grep('/^((\*|\[(?1)]|\((?1)\))(?1)?|)$/',$l));

使用好的旧的生成所有可能的然后过滤的方法。使用方式如下:

php -r "for(;$argv[1]--;$l=$c,$c=[])foreach($l?:['']as$s)for($n=5;$n--;)$c[]=$s.'*()[]'[$n];echo join(' ',preg_grep('/^((\*|\[(?1)]|\((?1)\))(?1)?|)$/',$l));" 4

1

Python,134个字节

from itertools import*
lambda n:[x for x in map(''.join,product('*()[]',repeat=n))if''==eval("x"+".replace('%s','')"*3%('*',(),[])*n)]

代表

未命名的函数,返回一个有效的length字符串列表n
表格所有长度n的字符的元组*()[],加入他们为使用字符串map(''.join,...)已被删除“对”平衡支架和过滤器的"*""()"以及"[]"反过来n次,检查结果为空字符串(n次是矫枉过正,特别是对于"*"但是高尔夫球手)。


1

视网膜,78字节

字节数假定为ISO 8859-1编码。

.+
$*
+%1`1
*$'¶$`($'¶$`)$'¶$`[$'¶$`]
%(`^
$';
)+`(\[]|\(\)|\*)(?=.*;)|^;

A`;

在线尝试!

说明

我正在生成所有可能的长度为5的字符串,然后过滤掉无效的字符串。

.+
$*

使用1数字将输入转换为一元。

+%1`1
*$'¶$`($'¶$`)$'¶$`[$'¶$`]

重复(+)替换1每行(%)中的第一个(),以使其制作该行的五个副本,每个可能的字符一个。这是通过使用前缀和后缀替换 $`$'构造每行的其余部分来完成的。

没有更多可替换的1时,此循环停止。至此,我们已经获得了所有可能的length字符串,N每行一个。

%(`^
$';
)+`(\[]|\(\)|\*)(?=.*;)|^;

这两个阶段分别针对每行(%)执行。第一阶段仅复制该行,并使用a ;分隔两个副本。

第二阶段是另一个环路(+),其反复移除[]()*从字符串的第一副本,在该行的开头去除分号(这是唯一可能的字符串已完全消失之后)。

A`;

有效的字符串是前面不再带有分号的字符串,因此我们只舍弃所有A包含分号的行()。


我尝试了输入5的onliny:好的。输入6时出现错误页面
edc65 '16

@ edc65对我有用,但是这种方法当然不是完全有效,因此需要花费几秒钟。您是指哪种错误页面?
马丁·恩德

输入5:3秒内回答。输入6:7秒钟后,在“输出”框中,我从代理服务器获取了可能是错误页面的html源。如果是超时,那么它是一个非常短的超时...我试图为输入6获取正确的测试用例,因为我的回答似乎可以输入5,但对于6或更多输入却是错误的
edc65 '16

@ edc65它肯定需要超过7秒的时间,并且TIO的超时是一分钟。我从未见过您描述的错误,可能值得在TIO聊天中提出(或者如果您更喜欢gitterGitHub)。至于参考输出,这是我得到输入6的结果:pastebin.com/WmmPPmrc(输入7耗时超过一分钟。)
Martin Ender

1

Python 3.5,146个字节

import re;from itertools import*;lambda f:{i for i in map(''.join,permutations("[()]*"*f,f))if re.fullmatch("(\**\[\**\]\**|\**\(\**\)\**)*|\**",i)}

与其他答案相比很长,但我目前能找到的答案最短。它采用匿名lambda函数的形式,因此必须以以下格式调用

print(<Function Name>(<Integer>))

输出一个Python 无序表示输入长度的所有可能的支架弦字符串。

例如,假设上述函数名为G,则调用G(3)将导致以下输出:

{'[*]', '*()', '*[]', '(*)', '***', '[]*', '()*'}

在线试用!(爱迪生)


但是,如果像我一样,你是不是真的使用内置插件简化的东西的粉丝,那么这里是我自己原来的答案使用任何外部库找到排列,目前站在高达288 237个字节

import re;D=lambda f:f and"for %s in range(%d)"%(chr(64+f),5)+D(f-1)or'';lambda g:[i for i in eval('["".join(('+''.join('"[()]*"['+chr(o)+'],'for o in range(65,65+g))+'))'+D(g)+']')if re.fullmatch("(\**\[\**\]\**|\**\(\**\)\**)*|\**",i)]

同样,与竞争性答案一样,该答案也采用lambda函数的形式,因此也必须以以下格式调用

print(<Function Name>(<Integer>))

并输出未排序字符串的Python 列表,该列表表示输入长度的所有大括号字符串。例如,如果将lambda作为调用,则这次输出将是以下内容:G(3)

['*()', '(*)', '*[]', '[*]', '()*', '[]*', '***']

而且,这其中也有很多比我其他的答案更快,能够找到长度的所有支柱串11在约115秒,这些长度10大约19秒,这些长度9大约4秒,以及那些长8在约0.73秒我的机器上,而我的答案竞争需要超过115秒的时间为输入6

在线试用!(爱迪生)


0

05AB1E,23字节

…[(*.∞sãʒ'*м„()„[]‚õ:õQ

问题发布后,其中某些功能可能已经实现。欢迎任何建议!

在线尝试!

怎么样?

…[(* - the string '[(*'
.∞ - intersected mirror, '[(*'=>'[(*)]'
s - swap the top two items, which moves the input to the top
ã - cartesian power
ʒ ...  - filter by this code:
  '*м      - remove all occurrences of '*'
  „()„[]‚  - the array ["()","[]"]
  õ        - the empty string ""
  :        - infinite replacement (this repeatedly removes "()", "[]", and "*" from the string
  õQ       - test equality with the empty string

我不知道05AB1E,但是也不能*在删除数组中吗?可以将õQ支票换成NOT吗?
硕果累累

第一个建议将不保存任何字节:'*м„()„[]‚õ:vs „()„[]‚'*«õ:(未经测试),因为没有命令来连接3个值AFAIK。第二个不起作用,因为没有一个NOT可以像字符串AFAIK那样运行。(据我所知在哪里表示“据我所知”)
扎卡里
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.