括号是否完全匹配?


56

您必须编写一个程序或函数,该程序或函数带有方括号,并输出该字符串是否完全匹配。您的程序应打印真实或虚假的值,并且IO可以采用任何合理的格式

规则和定义:

  • 出于此挑战的目的,“括号”是以下任意字符:()[]{}<>

  • 如果左括号和右括号的顺序正确且其中没有字符,则将一对括号视为“匹配”

    ()
    []{}
    

    或者,如果其中的每个子元素也都匹配。

    [()()()()]
    {<[]>}
    (()())
    

    子元素也可以嵌套在几层深处。

    [(){<><>[()]}<>()]
    <[{((()))}]>
    
  • 仅在以下情况下,字符串才被视为“完全匹配”:

    1. 每个字符都是一个括号,

    2. 每对支架都有正确的打开和关闭支架,并且顺序正确,并且

    3. 每个括号都匹配。

  • 您可以假设输入将仅包含可打印的ASCII

测试IO

以下是一些应返回真实值的输入:

()
[](){}<>
(((())))
({[<>]})
[{()<>()}[]]
[([]{})<{[()<()>]}()>{}]

以下是一些应返回假值的输出:

(               Has no closing ')'
}{              Wrong order
(<)>            Each pair contains only half of a matched element
(()()foobar)    Contains invalid characters
[({}<>)>        The last bracket should be ']' instead of '>'
(((()))         Has 4 opening brackets, but only 3 closing brackets.

像往常一样,这是代码高尔夫球,因此存在标准漏洞,并且最短答案以字节为单位。



7
潜在亲密投票者注意:我链接的挑战还包括括号类型的优先顺序,因此它们不能以任意顺序嵌套。我认为这使其与众不同。
Martin Ender

[}比赛吗?如果没有,这些规则将其排除在何处?
user207421'4

2
@EJP不,不是。Each pair of brackets has the correct opening and closing bracket and in the right order.
DJMcMayhem

6
我会在“方括号
leo

Answers:


17

05AB1E,19个字节

输入以引号引起。码:

"[](){}<>"2÷)"":g2Q

好吧,发现了许多错误和未实现的功能。说明:

"[](){}<>"           # Push this string
          2÷         # Split into pieces of two
            )        # Wrap it into an array (which should not be needed)
             ""      # Push an empty string
               :     # Infinite replacement

这实际上是一个棘手的部分。伪代码中的内容是:

input().replace(['[]', '()', '{}', '<>'], "")

这部分来自05AB1E代码

if type(b) is list:
    temp_string = temp_string_2 = str(a)
    while True:
        for R in b:
            temp_string = temp_string.replace(R, c)
        if temp_string == temp_string_2:
            break
        else:
            temp_string_2 = temp_string
    stack.append(temp_string)

如您所见,这是无限替换(完成直到字符串不再更改为止)。因此,我不必担心将替换设置为循环,因为它已经内置。之后:

                g    # Take the length of the final string
                 2Q  # Check if equal with 2 (which are the quotes at the end)

使用CP-1252编码。在线尝试!(由于不建议使用上述版本,因此进行了轻微修改)。


1
打高尔夫球不错!
SamyQc '16

1
这是之前õ添加的吗?
扎卡里

@扎卡里是的,这是正确的
阿德南

33

脑高射炮1101,1085,981个字节

{(<(({}))((((()()()()()){}){}){})({}[{}]<(())>){((<{}{}>))}{}>{({}<>)(<>)}{}<(({
}))((((()()()()()){}){}){}())({}[{}]<(())>){((<{}{}>))}{}>{({}<>)({}[{}](<()>)){
{}{}(<(())>)}{}{<>{{}}<>{{}}((<()>))}{}(<>)}{}<(({}))(((((()()()()()){}){})){}{}
)({}[{}]<(())>){((<{}{}>))}{}>{<({}()<>)>()(<>)}{}<(({}))(((((()()()()()){}){})(
)){}{})({}[{}]<(())>){((<{}{}>))}{}>{<({}()<>)>()({}[{}](<()>)){{}{}(<(())>)}{}{
<>{{}}<>{{}}((<()>))}{}(<>)}{}<(({}))((((()()()){}){}()){({}[()])}{})({}[{}]<(()
)>){((<{}{}>))}{}>{<({}()()<>)>()(<>)}{}<(({}))((((((()()()()()){})){}{}())){}{}
)({}[{}]<(())>){((<{}{}>))}{}>{<({}()()<>)>()({}[{}](<()>)){{}{}(<(())>)}{}{<>{{
}}<>{{}}((<()>))}{}(<>)}{}<(({}))((((((()()()()()){}){}){}())){}{})({}[{}]<(())>
){((<{}{}>))}{}>{<({}()()()<>)>()(<>)}{}<(({}))((((((()()()()()){}){}){}())()){}
{})({}[{}]<(())>){((<{}{}>))}{}>{<({}()()()<>)>()({}[{}](<()>)){{}{}(<(())>)}{}{
<>{{}}<>{{}}((<()>))}{}(<>)}{}<{}>[()]){<>{{}}(<()>)<>{{}}(<()>)}{}}<>([]<>)({}<
(())>){((<{}{}>))}{}

在线尝试!

这是980个字节的源代码,并且+1-a标志允许ASCII输入(但十进制输出)

这是我长时间以来一直想写的答案。至少六个月。我之所以等待发布,是因为我知道应对这一挑战将使人难以接受。但这是值得的,因为一个非常重要的原因:源代码本身是一个真实的输入,这是该语言本身的全部要点。

正如我在这里所写的那样,这个问题是促使我写脑筋急转弯的原因。

在我写了括号是否完全匹配吗?之后不久,我想知道仅使用匹配的括号可以存储多少信息。对我而言突出的一件事是,即使您只有4种“原子”:

(){}[]<>

您实际上有8个单位要传达的信息,因为这些括号类型中的每一个都可以为空,或者之间也可以有其他括号,这是根本不同的信息。因此,我决定写一种只允许使用匹配括号的语言,其中空括号传达的内容不同于括号内带有其他括号的内容。

这个答案大约花了两个小时来写。我承认它打的不好,主要是因为每种支架类型都重复了很多代码。但是我很惊讶我完全能够写出答案,特别是考虑到Brain-Flak是

极简主义的esolang设计使用起来很痛苦

我打算稍后再打下去,但是我还是想把它弄出来。

我有详细的解释,但是它的长度约为6000个字符,因此我认为将整个内容粘贴到此答案中是不明智的。如果需要,可以在这里阅读。我将在这里添加一个简短的解释。

基本思想是,我们对堆栈上的每个字符重复以下步骤:

  • 我们检查每个字符,看是否与任何括号匹配。如果是开括号,则根据以下映射将数字压入另一个堆栈:

    ( = 1
    < = 2
    [ = 3
    { = 4
    
  • 然后我们检查它是否与任何右括号匹配。如果是这样,我们将等号推入备用堆栈,就像打开方括号一样。然后,我们检查前两个数字是否相等。如果是,则两者都将弹出,程序将继续正常运行。如果不是,我们清除两个堆栈(以停止循环),然后将一个堆栈推入备用堆栈。这本质上是一个“ break”语句。

  • 在检查了8种括号类型之后,我们将该循环的值推入循环中。由于我们将其中大部分归零,因此与方括号进行比较时,唯一具有条件的代码段是条件代码。因此,如果匹配任何一个括号,则整个循环的值为1。如果都不匹配,则整个循环的值为0。在这种情况下,我们将清除两个堆栈并将0压入备用堆栈。同样,这就像一个“ break”语句。

在这个主循环运行之后,剩下的就相当简单了。我们在(空)主堆栈上,而备用堆栈为空(如果括号匹配),否则为非空。所以我们运行这个:

#Toggle to the alternate stack
<>

#Push this stack-height onto main-stack
([]<>)

#Logical not
({}<(())>){((<{}{}>))}{}

这会将0或1压入主堆栈,并在程序结束时隐式打印。



修订版

  • 删除了一些推送弹出式冗余

  • 更改了我的零计数器逻辑


1
Awwwwwweeeeesommmmeeeee!
Arjun

23

脑高射炮204个 196 190字节

{({}<>)<>((((()()()()()){})(({}){})())({}(({})((({}){})(<()>))))())(({<({}<>[({})])>[()]{()(<{}>)}{}<>}{}()<({}<>[({})]){(<{}({}())>)}{}<>>)){(<({}{}<>[{}]{}<>)>)}{}{<>{{}}}{}}<>((){[()]<>})

在线尝试!

-8字节归功于Wheat Wizard。-6个字节,感谢Jo King。

说明

该程序将所有当前未封闭括号中的字符代码存储在第二个堆栈中。方括号对<>[]{}各自的字符代码相差2,因此无需专门检查它们。该对之间的差()仅为1,因此我们会进行(专门检查,并在继续操作之前有效地减少该字节(实际上每隔一个字节增加一个字节)。

# While there are bytes left to process
{

 # Move byte to second stack
 ({}<>)<>

 # Push 40, 0, 40, 60, 91, 123: (, then null, then all four opening brackets
 ((((()()()()()){})(({}){})())({}(({})((({}){})(<()>))))())

 ((

   # For each opening bracket type:
   {

    # Evaluate as zero
    <

     # Compute difference between bracket type and input byte
     ({}<>[({})])

    >

    # Evaluate loop iteration as -1 if equal, 0 otherwise
    [()]{()(<{}>)}{}<>

   }

   # Remove the 0 that was inserted to terminate that loop
   {}

   # Add 1 to result
   ()

   # Evaluate rest of this expression as zero
   <

    # Determine whether the byte is open parenthesis
    ({}<>[({})])

    # If not:
    {

     # Add 1 to byte and break if
     (<{}({}())>)

    }{}

    # Return to main stack
    <>

   >

 # Push result twice (0 if matched an opening bracket, 1 otherwise)
 ))

 # If byte was not an opening bracket:
 {

  # Push zero to break out of if
  (<

    # Push (open bracket + 2 - byte) below that zero
    ({}{}<>[{}]{}<>)

  >)

 }{}

 # If byte was neither an opening bracket nor the appropriate closing bracket:
 {

  # Clear alternate stack and stay there to break out of main loop early
  <>{{}}

 }{}

# End of main loop
}

# If a prefix was invalid, the top of the other stack is the same nonzero value
# that made us break out in the first place. If the string was a valid prefix,
# the other stack contains every unclosed bracket.  If the string is balanced,
# there are none of these. Thus, the other stack is empty if the
# brackets are balanced, and has a nonzero value on top otherwise.

# Push 1 on other stack if empty, and 0 on current stack otherwise
<>((){[()]<>})

“逻辑上没有区别”(也称为“相等”)可以缩短为([{}]<>({}))((){[()](<{}>)}{})
Wheat

我想你可以替换与上次检查({<>[()]}())为-6字节
乔金

@JoKing谢谢。我认为我永远不会发现这一点。
Nitrodon '18 -4-27

是的,我在自己的答案中找到了答案,并意识到它也适用于您的答案
Jo King

13

JavaScript(ES6),52 50字节

f=s=>(t=s.replace(/\(\)|\[]|{}|<>/,''))==s?!s:f(t)

重复删除方括号,直到结果与原始结果相同为止,然后返回false,除非字符串现在为空。

编辑:由于@ edc65,节省了2个字节。



11

CJam,25 24 23 21字节

感谢Sp3000节省2个字节。
感谢jimmy23013节省了2个字节。

q_,{()<>}a`$2/*{/s}/!

测试套件。

基本工作原理相同,其他的答案:我们重复地移动()[]<>{}从字符串,并检查是否我们最终空字符串。为了避免必须检查何时完成,我们将成对的N时间删除为N字符串的长度,其中总是字符串的长度(因为每次迭代都会删除至少两个字符,除非我们完成)。我很高兴看到它没有击败Retina。:)(尽管Pyth或Jelly可能...)

这里有一个有趣的高尔夫技巧:要获得琴弦,()<>[]{}我们使用以下方法:

{()<>}a`$

的,{()<>}仅仅是一个块(即一个函数),其中包含了其他括号作为代码。随着a我们将块包装在数组中。所述`stringifies该阵列,它给出"[{()<>}]"。最后,我们用排序字符串$,将括号重新排列为()<>[]{}


我不熟悉您的语言,但是您对打高尔夫球技巧的描述使它听起来()<>[]{}`同样有效,并且字节数相同,对吗?
Mooing Duck 2016年

1
@MooingDuck否,因为()<>有四个运算符(递减,递增,然后根据操作数进行比较或截断),这些运算符将立即执行,而{}表示一个块(CJam等效于一个函数),即刚刚压入的一段代码放在堆栈上,而不立即对其进行评估。这就是为什么我需要{}包装()and 的原因<>,但是a用于将所有内容放入数组中的时间要短于[...]
Martin Ender

10

Python,67个字节

lambda s:eval("s"+".replace('%s','')"*4%([],(),{},'<>')*len(s))==''

生成并评估一个看起来像的表达式

s.replace('[]','').replace('()','').replace('{}','').replace('<>','').replace('[]','').replace('()','').replace('{}','').replace('<>','')

并检查结果是否为空。

Sp3000通过指出[],(),{}可以被加引号而无需引号的方式节省了8个字节,因为它们是Python对象,并且不需要两个parens。


8

Yacc,119个字节

不使用正则表达式/替换。

%%input:r;r:%empty|'['r']'r|'{'r'}'r|'('r')'r|'<'r'>'r;%%yylex(){return getchar();}main(){return yyparse();}yyerror(){}

不打高尔夫球

%%                              # Grammar in BNF
input:
  r;
r:
  %empty
| '['r']'r
| '{'r'}'r
| '('r')'r
| '<'r'>'r;
%%                              # Minimal parser invocation and lexer
yylex(){return getchar();}
main(){return yyparse();}
yyerror(){}

汇编

yacc -o bracket.c bracket.y
cc -o bracket bracket.c

用法

~/ % echo -n "<()[]>" | ./bracket
~/ %
~/ % echo -n "{" | ./bracket
~/ 1 %                                                                         :(

7

Pyth,31 25 24字节

由于FryAmTheEggMan删除了1个字节,因此高尔夫球减少到25个字节

VQ=:Q"<>|\[]|{}|\(\)"k;!

在这里尝试:测试套件

我仍然是Pyth的新手,感谢您的帮助。

说明

VQ                         For N in range(0, len(z)), with Q being the evaluated input.
                           Optimal solution would be to use range(0, len(z)/2) instead, but it add two bytes.
  =:Q"<>|\[]|{}|\(\)"k     assign Q without {}, [], <> nor () (regex replacement) to Q
                      ;    End of For loop
                       !   Logical NOT of Q's length (Q is the input, but has gone several times through y, and Q is implicit).
                           This last operation returns True if len(Q) is 0 (which means all brackets were matched), False otherwise

顺便说一句,恭喜另一个Pyth答案(当前为20个字节)


欢迎来到编程难题和Code Golf!
阿德南

@Adnan谢谢!这是我的第一次高尔夫!
FliiFe

不错的第一场高尔夫球!随着一些清理和东西,你可以得到25: Vz=:z"<>|\[]|{}|\(\)"k;!z。特别要注意的是,l如果实际上不需要数字,则基本上不需要使用,并=自动猜测表达式中使用的第一个变量。让我知道您是否想在Pyth聊天室中解释其他问题:)
FryAmTheEggman '16

@FryAmTheEggman谢谢!我不知道这l是不必要的,很高兴知道。起初,我声明了一个函数是因为我的逻辑不同,却忘记了删除它。我可以附上您对我的回答吗?(我是新手>。<)
FliiFe

3
通常,如果将其张贴在评论中,则评论作者希望您使用它。因此,继续前进!:)
FryAmTheEggman '16

6

Pyth,20个字节

!uuscNTc"[](){}<>"2G

在线试用:测试套件

删除重复的出现[]()<>{}通过拆分和重新合并。检查结果字符串是否为空。


4

Javascript ES6,54个字节

f=_=>_.match(x=/\(\)|\[]|{}|<>/)?f(_.replace(x,'')):!_

使用递归替换实现。很简单。



4

Perl,34 33字节

包括+2 -lp

使用STDIN上的输入运行:

./brackets.pl <<< "{<>()}"

brackets.pl

#!/usr/bin/perl -lp
s/\(\)|\[]|<>|{}//&&redo;$_=!$_

查找第一个括号对,中间没有任何东西,只要有,就将其删除。然后检查最终字符串是否为空。


不行s/\(\)|\[]|<>|{}//&&redo;$_=!$_吗 :)
Dada

如果您还可以提供解释,那就太好了。
Prashant Pokhriyal

@Dada当然。我一定要老了..
Ton Hospel

4

Brain-Flak,204字节

(()){{}{({}<>)<>}<>({<(<(({})<>)>)(((((((([(())()()()]){}){}){}())(()))(((())()){}()){})){})(({<(({}<>{}[()]))>(){[()](<{}>)}{}<>}{}))<>{}<>{{}({}[({})]<>({})){(<>)(<>)}{}{}(<>)}{}>{}<>}<>)}{}((){<>[()]})

在线尝试!

不及Nitroden的答案那么短,而是使用了一种非常不同的方法。这一次反复遍历输入,每次都删除相邻的匹配括号对,直到没有剩下的为止。此时,如果堆栈上还剩下任何东西,则说明该字符串未完全匹配。

说明:

(())  Push 1 to simulate the check at the start of the loop
{  While check
	{}           Pop check
	{({}<>)<>}<> Reverse input
	({           Loop over input
		< Don't push the values of these calculations
		(<(({})<>)>)  Create a copy of the top of the input and push to the other stack
		(((((
		((([(())()()()]){}){}){}())
		(()))
		(((())()){}()){})
		){})          Push the differences in values of the end brackets 
		(({<(({}<>{}[()]))>(){[()](<{}>)}{}<>}{}))  If the copy is the same as any of these, push the difference between the other bracket twice
		<>{}<>  Pop copy
		{  If this character is a start bracket
			{}({}[({})]<>({}))  Check if the next character is the end bracket
			{(<>)(<>)}{}          If not, push a 0 to each stack as buffer
			{}       Pop the top of the input stack, either the start bracket if they matched or the buffer 0
			(<>)     Push 0 to other stack to end check
		}{}>
		{}   Pop the top of the other stack
		         If the character was not an end bracket, pop the copy of check, which is 0
		         If it was, but didn't match the next character, pop the buffer 0
		         If the brackets matched, pop the end bracket and add it to the loop total
	<>}	Repeat with the rest of the input
	<>)	Push the loop total
		If any brackets were matched, the loop total is non zero
}{}
((){<>[()]}) If there is anything left on the stack, push 0 to the other stack, otherwise push 1

3

Brainfuck,132个字节

+>,[[<->>+>[-]<<-]<[>+>[<+<+>>>+<-]+++++[>--------<-]>[<<+>++++[>-----<-]>[<++++
+[>------<-]>-[<++++[>--------<-]>[,>]]]]<],]<<[>]>.

格式:

+>,
[
  [<-> >+>[-]<<-]
  <
  [
    not matching closing bracket
    >+>[<+<+>> >+<-]
    +++++[>--------<-]
    >
    [
      not open paren
      <<+>
      ++++[>-----<-]>
      [
        not open angle bracket
        <+++++[>------<-]>-
        [
          not open square bracket
          <++++[>--------<-]>
          [
            not open brace
            ,>
          ]
        ]
      ]
    ]
    <
  ]
  ,
]
<<[>]
>.

期望输入时没有尾随换行符。打印\x00为false和\x01true。

在线尝试。

方法:保持以开头的堆栈\x01,并在遇到打开支架时推入相应的关闭支架。在检查当前字符是否为左括号之前,首先要检查其是否等于堆栈顶部的右括号,如果是,则将其弹出。如果既不是正确的右括号也不是右括号,则在将指针向右移动时消耗掉其余的输入。最后,检查指针是否位于initial的旁边\x01


2

Grime v0.1,34个字节

M=\(M\)|\[M\]|\{M\}|\<M\>|MM|_
e`M

打印1匹配项和0不匹配项。 在线尝试!

说明

Grime是我为应对这一挑战而设计的2D模式匹配语言;它也可以用来匹配一维字符串。这是我的第一个答案。我今天确实修改了Grime,但只是更改了一个语法元素(`而不是,)的字符,因此它不会影响我的分数。

M=                         Define pattern called M that matches:
\(M\)|\[M\]|\{M\}|\<M\>      a smaller M inside matched brackets,
|MM                          or two smaller Ms concatenated,
|_                           or the empty pattern.
e`M                        Match the entire input against M.

2

Reng v.3.3,137个字节,无竞争

在这里尝试!

aií0#zl2,q!~1ø
:"]"eq!v:"}"eq!v:">"eq!v:")"eq!v)1z+#z
ve¤[2-2<       <       <     +1<
>]?v$$$zÀ0#z >ðq!vlqv¤l2%[1Ø
   \$2+)1z+#z/   ~n1/

高尔夫还有很多事情要做,但至少能奏效。ð在此挑战之后,我添加了一个命令来跟踪堆栈,以便可以远程/轻松地进行操作。我将对此稍作解释,但是它通常会跟踪所有迭代的字符串并寻找重复的字符串。如果有重复,则该字符串不可约。否则,该字符串将减少为空字符串/堆栈,并输出1。否则,将不会产生任何输出。


2

PowerShell v2 +,63 62字节

param($a)for(;$a-ne$b){$a=($b=$a)-replace"\[\]|\(\)|<>|{}"}!$a

无法完全捕获JavaScript,但目前正在淘汰其他非eolang。

类似的做法为其他答案:一个简单的循环一直持续,只要我们可以删除的一个[]()<>(与几个多余的字符,因为我们需要转义正则表达式特价)。在此过程中,我们将$b用作帮助者来记住上一个循环的$a设置。未初始化的变量是$null,因此第一次遇到循环时,$a显然不等于$null

在循环的最后,$a为空或为空,并且该字符串的Boolean-not为Trueor False

PS C:\Tools\Scripts\golfing> .\are-the-brackets-fully-matched.ps1 "[({})]"
True

PS C:\Tools\Scripts\golfing> .\are-the-brackets-fully-matched.ps1 "[({])}"
False

2

C,121个 122 114字节

感谢@xsot,减少了8个字节!

a[99],i,k;main(c){for(;read(0,&c,!k);c%7&2?k|=a[i--]^c/9:(a[++i]=c/9))k|=!strchr("()[]{}<>",c);putchar(48+!k*!i);}

使用堆栈。


我喜欢c%7&2。实际上,您不需要k。相反,您可以简单地增加i要修改的位置,k因为i无论如何最终都需要检查是否为零。事情是这样的(未测试的代码): a[99],i;main(c){for(;read(0,&c,1);c%7&2?i+=a[i--]^c/9:(a[++i]=c/9))i+=!strchr("()[]{}<>",c);putchar(48+!i);}
xsot

@xsot-增加我的工作量吗?我们还需要避免用负值对数组下标,因此我们必须在for中测试i或k。
mIllIbyte

啊,我明白了。尽管如此,仍有改进的空间:a[99],i,k;main(c){for(;read(0,&c,!k);c%7&2?k|=a[i--]^c/9:(a[++i]=c/9))k|=!strchr("()[]{}<>",c);putchar(48+!i*!k);}
xsot

@xsot-谢谢!总结一下节省,读取保存的5个字节,^保存一个,条件运算符的中间操作数保存2。我很惊讶,条件运算符的中间操作数可以是赋值。我以为会出现错误,例如“ missing:before =”。
mIllIbyte

@xsot-我尝试增加i而不是使用k,如您首先建议的那样:a[99],i;main(c){for(;read(0,&c,1);c%7&2?i+=a[i]^c/9?1:-1:(a[++i]=c/9))i+=!strchr("()[]{}<>",c);putchar(48+!i);}但这对于诸如之类的输入尚不起作用())),因为从堆栈中“弹出”实际上并未将数组中的值归零。
mIllIbyte

2

Java 7中,156个 151字节

class A{public static void main(String[]a){for(int i=0;i<-1>>>1;++i,a[0]=a[0].replaceAll("<>|\\[]|\\(\\)|\\{}",""));System.out.print(a[0].isEmpty());}}

我并不期望这会赢得任何奖项,但是我还没有看到Java的答案。此外,我喜欢潜伏在PPCG周围,我很高兴能够对其他答案进行投票/评论。

输入作为程序参数给出。它遵循与此处许多其他答案相同的格式,因为它在循环中执行正则表达式替换。最初,我使它循环N次,其中N是原始字符串的长度,但是循环到Integer.MAX_VALUE的时间更短:]。这应该没问题,因为Java Integer.MAX_VALUE中a的最大长度,String因此隐式假设输入的长度是Java可以处理的。由于循环的原因,运行时非常糟糕(在我的笔记本电脑上花费了大约20分钟),但是我对此没有任何限制。


2

Haskell,151个字节

infix 1#
'(':x#y=x#')':y
'<':x#y=x#'>':y
'[':x#y=x#']':y
'{':x#y=x#'}':y
')':x#')':y=x#y
'>':x#'>':y=x#y
']':x#']':y=x#y
'}':x#'}':y=x#y
""#""=1
_#_=0

在线尝试!


一些事情:由于(#)需要使用空字符串作为第二个参数来调用该函数,因此需要将其计入(#"")字节数。也只有TrueFalse被认为truthy / falsy,请参阅指南高尔夫球规则
Laikoni'2

1
但是,带括号的四行可以替换为a:x#b:y|a==b=x#y,使字节数减少至113:在线尝试!
Laikoni'2

2
109个字节:在线尝试!
Laikoni '18

2

Python 2.7,96个字节

def r(s):i=max(map(s.find,['()','[]','{}','<>']));return not len(s)if i<0 else r(s[:i]+s[i+2:])

2
欢迎光临本站!
DJMcMayhem

1

Python 2,80个字节

def m(s,i=0):exec's=s.replace("[({<])}>"[i%4::4],"");i+=1;'*4*len(s);return"">=s

1

朱莉娅51字节

~z=z==(n=replace(z,r"\(\)|\[]|{}|<>",""))?z=="":~n

几个选项中最不疯狂的。毫不奇怪,利用正则表达式的功能是字符串匹配的最短路径,但这实际上仅在匹配模式是规则的情况下适用。尝试执行PCRE递归模式最终会膨胀代码的大小,方法是查看整个字符串是否匹配,或者锚定两端,然后创建一个结构以指定用于regex递归的内部主体。两者都不美观或不利于打高尔夫球。

说明:

~z=                            # Define ~z to be the following:
    z==(                       # If z is equal to                                     
        n=replace(z,           # z with the replacement of 
            r"\(\)|\[]|{}|<>", # adjacent matching brackets ((),[],{}, or <>)
            ""                 # with empty strings
        )                      # (which is assigned to n)
    )?z==""                    # whether z is an empty string
    :~n                        # else ~ applied to the substituted string

该函数从其唯一的参数中反复删除相邻的括号对,如果可以通过这种方式派生空字符串,则返回true。


1

sed,39个36字节(代码为34个,-r为2个)

:a
s/\(\)|\[]|<>|\{}//;ta
/./c0
c1

在线尝试!

sed版本的标准方法。需要扩展的正则表达式(sed -r

牛嘎嘎声节省了3个字节


您可以删除ais :ata保存字节
Kritixi Lithos 17-4-29的

@KritixiLithos 显然,这是GNU sed 中的一个错误,已在4.3中删除。如果此条目距离领导者足够近,有机会赢得比赛,我可能会丢掉这些角色,但由于并非如此,所以我将其保留为更便于携带的形式,以便它不会停止工作随着更多系统升级到4.3。

1
回顾这一点,我确定您也可以将qfrom /./拖放到括号内。在线尝试!这是因为c
hange

@Cowsquack谢谢。编辑。

0

05AB1E,9个字节

žu2ôõ:g2Q

输入以引号引起。

在线尝试!

说明:

žu          # Push "()<>[]{}"
  2ô        # Split into pieces of size 2
    õ       # Push empty string
            # Implicit input
      :     # Infinite replacement
       g2Q  # Is length equal to 2?
            # Implicit print

0

Clojure,153个字节

比C和Brainfuck还要长的答案:o

(defn f[[s & r]](if s(let[[a b](split-at(.indexOf(reductions + 1(for[c r](get(zipmap[s({\(\)\[\]\{\}\<\>}s)][1 -1])c 0)))0)r)](and(not=()a)(f(butlast a))(f b))))1)

不使用正则表达式,而是使用第一个字符来确定结束标记是什么,并找到该括号处于平衡状态的第一个索引(累计和为零)。然后反复检查方括号内和方括号后的内容是否有效。

要看看是否有更好的方法...


0

Lua,295字节

f = false g = string.gsub t=table s={}b=io.read()for c in b:gmatch('.')do if c:find("[%[<{%(]")then s[#s + 1] = g(g(g(g(c,"<",">"),"{","}"),"%[","]"),"%(",")")elseif c:find("[%]>}%)]")then if t.remove(s)~=c then print(f)return end else print(f)return end end if#s>0 then print(f)else print(1)end

非高尔夫版本

f = false
g = string.gsub
t=table
s={} --Define a stack of opening brackets
b=io.read() --get the input
for c in b:gmatch('.') do   --for every character
    if c:find("[%[<{%(]") then
        s[#s + 1] = g(g(g(g(c,"<",">"),"{","}"),"%[","]"),"%(",")") --if the current character is an opening bracket, push the closing bracket onto the stack
    elseif c:find("[%]>}%)]") then
        if t.remove(s)~=c then
            print(f) --if the character is a closing bracket, pop the closing bracket off the stack and test if they match, if not print false
            return
        end
    else 
        print(f) --if the character is not a bracket print false
        return
    end
end
if #s>0 then
    print(f) --if there are still brackets on the stack print false
else
    print(1) --print 1 there are no brackets on the stack
end

在线尝试!



0

R,298

function(.){s=strsplit;u=paste0;.=s(.,"")[[1]];p=s("><)(}{][","")[[1]];.[!.%in%p]="§";for(i in 1:4*2){.[.==p[i]]=sprintf("S('%s',{",p[i]);.[.==p[i-1]]=sprintf("},'%s');",p[i])};S=function(H,B,T)if(H!=T)stop();r=try(eval(parse(,,u(.,collapse=""))),1);if(inherits(r,"try-error"))FALSE else TRUE}

此处的方法是将序列转换为R代码,然后尝试解析和评估它。如果那给出了错误,则返回FALSE

但是有一个小问题...的r的括号规则是不同的,所以<>没有括号可言,而其他类型的都有自己的规则。这可以通过一种革命性的方法来解决-吱吱声功能,其唯一功能是在其头和尾以不同方式吱吱声时发出错误信号。

例如,[]将转换为S('[', {}, ']'),其中S定义为...

S=function(H,B,T)if(H!=T)stop() 

因为头部吱吱声和尾部吱吱声匹配,所以不会引发任何错误。

其他一些示例(左侧部分是一系列括号,右侧部分是将其转换为可以评估的有效R代码):

[}     -->  S('[', {}, '}')     # squeaks an error
[()]   -->  S('[', {S('(',{},'(')}, "[")
({[]}) -->  S('(',{S('{',{S('[',{},'[');},'{');},'(');

方括号的其他一些序列将导致解析错误:

[[)    -->   S('[',{S('[',{},'('); 

因此,其余部分仅捕获错误,如果有错误,则返回FALSE,如果没有,则返回TRUE。

可读代码:

 sqk <- function(.){
   s=strsplit;u=paste0
   .=s(.,"")[[1]]            # break the argument up into 1-character pieces
   p=s("><)(}{][","")[[1]]   # vector of brackets
   .[!.%in%p]="§"            # replace anything besides brackets by § (--> error)
   for(i in 1:4*2){     
     .[.==p[i]]=sprintf("S('%s',{",p[i])    # '<' -->   S('<',{     ... etc
     .[.==p[i-1]]=sprintf("},'%s');",p[i])  # '>' -->   },'<');     ... etc  
   }
   S=function(H,B,T)if(H!=T)stop()          # define the working horse
   r=try(eval(parse(,,u(.,collapse=""))),1) # evaluate the sequence
   if(inherits(r,"try-error"))FALSE else TRUE   # any errors?
   }

将其应用于示例案例:

truthy<-readLines(textConnection("()
[](){}<>
(((())))
({[<>]})
[{()<>()}[]]
[([]{})<{[()<()>]}()>{}]"))
falsy<-readLines(textConnection("(
}
(<2)>
(()()foobar)
[({}<>)>
(((()))"))
> sapply(truthy,sqk)
                      ()                 [](){}<>                 (((()))) 
                    TRUE                     TRUE                     TRUE 
                ({[<>]})             [{()<>()}[]] [([]{})<{[()<()>]}()>{}] 
                    TRUE                     TRUE                     TRUE 
> sapply(falsy,sqk)
           (            }        (<2)> (()()foobar)     [({}<>)>      (((())) 
       FALSE        FALSE        FALSE        FALSE        FALSE        FALSE 
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.