Các dấu ngoặc có khớp hoàn toàn không?


56

Bạn phải viết một chương trình hoặc hàm lấy một chuỗi dấu ngoặc và xuất ra xem chuỗi đó có khớp hoàn toàn hay không. Chương trình của bạn nên in một giá trị trung thực hoặc giả , và IO có thể ở bất kỳ định dạng hợp lý nào .

Quy tắc và định nghĩa:

  • Đối với mục đích của thử thách này, "khung" là bất kỳ ký tự nào trong số này : ()[]{}<>.

  • Một cặp ngoặc được coi là "khớp" nếu dấu ngoặc mở và đóng theo đúng thứ tự và không có ký tự bên trong chúng, chẳng hạn như

    ()
    []{}
    

    Hoặc nếu mọi phân lớp bên trong của nó cũng được khớp.

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

    Subelements cũng có thể được lồng nhiều lớp sâu.

    [(){<><>[()]}<>()]
    <[{((()))}]>
    
  • Một chuỗi được coi là "Hoàn toàn khớp" khi và chỉ khi:

    1. Mỗi ký tự là một dấu ngoặc,

    2. Mỗi cặp ngoặc có khung mở và đóng đúng và theo đúng thứ tự, và

    3. Mỗi khung được khớp.

  • Bạn có thể cho rằng đầu vào sẽ chỉ chứa ASCII có thể in được .

Kiểm tra IO

Dưới đây là một số đầu vào sẽ trả về giá trị trung thực:

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

Và đây là một số kết quả đầu ra sẽ trả về giá trị giả:

(               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.

Như thường lệ, đây là môn đánh gôn, vì vậy các sơ hở tiêu chuẩn được áp dụng và câu trả lời ngắn nhất tính theo byte sẽ thắng.



7
Lưu ý đối với các cử tri gần gũi tiềm năng: Thách thức tôi liên kết cũng bao gồm một thứ tự ưu tiên cho các loại khung để chúng không thể được lồng trong một thứ tự tùy ý. Tôi nghĩ rằng làm cho nó đủ khác nhau.
Martin Ender

[}một trận đấu? Và nếu không, nó bị loại trừ bởi những quy tắc này ở đâu?
dùng207421

2
@EJP Không, không phải vậy. Each pair of brackets has the correct opening and closing bracket and in the right order.
DJMcMayhem

6
Tôi sẽ nâng cấp giải pháp đầu tiên trong Chân đế
leo

Câu trả lời:


17

05AB1E , 19 byte

Đầu vào được đưa ra trong dấu ngoặc kép . Mã số:

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

Chà, rất nhiều lỗi và các tính năng chưa được thực hiện đã được tìm thấy. Giải trình:

"[](){}<>"           # 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

Đây thực sự là một phần khó khăn. Điều này trông giống như trong mã giả là:

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

Phần này được bao phủ bởi phần này từ mã 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)

Như bạn có thể thấy, đây là sự thay thế vô hạn (được thực hiện cho đến khi chuỗi không thay đổi nữa). Vì vậy, tôi không phải lo lắng về việc đặt thay thế thành một vòng lặp, vì điều này đã được tích hợp sẵn. Sau đó:

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

Sử dụng mã hóa CP-1252 . Hãy thử trực tuyến! (sửa đổi một chút vì phiên bản trên không được dùng nữa).


1
Chơi golf độc đáo!
SamyQc

1
Đây có phải là trước khi õđược thêm vào?
Zacharý

@ Zacharý Vâng, đúng vậy
Adnan

33

Brain-Flak , 1101, 1085 , 981 byte

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

Hãy thử trực tuyến!

Đây là 980 byte mã nguồn và +1cho -acờ cho phép đầu vào ASCII (nhưng đầu ra thập phân)

Đây là một câu trả lời tôi đã muốn viết trong một thời gian rất dài. Ít nhất 6 tháng. Tôi đã chờ để đăng bài này vì tôi biết rằng việc trả lời thử thách này sẽ cực kỳ khó khăn trong việc cân não. Nhưng nó đáng giá vì một lý do rất quan trọng: Bản thân mã nguồn là một đầu vào trung thực, đó là toàn bộ quan điểm của chính ngôn ngữ này.

Và khi tôi viết về đây , câu hỏi này là điều đã truyền cảm hứng cho tôi để viết bộ não.

Ngay sau khi tôi viết Các dấu ngoặc có khớp hoàn toàn không?, Nó làm tôi tự hỏi bạn có thể lưu trữ bao nhiêu thông tin chỉ với dấu ngoặc phù hợp. Một điều nổi bật với tôi, là mặc dù bạn chỉ có 4 "nguyên tử" loại:

(){}[]<>

bạn thực sự có 8 đơn vị thông tin cần truyền đạt, vì mỗi loại khung này có thể trống hoặc có các dấu ngoặc khác ở giữa, là những phần thông tin khác nhau cơ bản. Vì vậy, tôi đã quyết định viết một ngôn ngữ chỉ được phép cho dấu ngoặc phù hợp và trong đó dấu ngoặc rỗng truyền tải một cái gì đó khác với dấu ngoặc với các dấu ngoặc khác bên trong chúng.

Câu trả lời này mất khoảng hai giờ để viết. Tôi sẽ thừa nhận rằng nó khá tệ khi chơi golf, chủ yếu là do rất nhiều mã được lặp lại cho từng loại khung. Nhưng tôi rất ngạc nhiên khi tôi có thể viết một câu trả lời, đặc biệt là cho rằng Brain-Flak là

Một esolang tối giản được thiết kế để gây đau đớn khi sử dụng

Tôi sẽ cố gắng đánh gôn nó sau, nhưng dù sao tôi cũng muốn đưa nó ra ngoài đó.

Tôi có một lời giải thích chi tiết, nhưng nó dài khoảng 6 nghìn ký tự, vì vậy tôi nghĩ sẽ không khôn ngoan nếu dán toàn bộ điều này vào câu trả lời này. Bạn có thể đọc qua nó ở đây nếu bạn muốn. Tôi sẽ thêm một lời giải thích ngắn hơn ở đây.

Ý tưởng cơ bản là chúng tôi lặp lại các bước sau cho mỗi ký tự trên ngăn xếp:

  • Chúng tôi kiểm tra từng ký tự để xem nếu nó phù hợp với bất kỳ khung. Nếu đó là dấu ngoặc mở, chúng ta sẽ đẩy một số lên ngăn xếp khác theo ánh xạ sau:

    ( = 1
    < = 2
    [ = 3
    { = 4
    
  • Sau đó, chúng tôi kiểm tra xem nếu nó phù hợp với bất kỳ khung đóng cửa. Nếu vậy, chúng ta sẽ đẩy số tương đương lên ngăn xếp thay thế, giống như để mở ngoặc. Sau đó , chúng tôi kiểm tra xem hai số trên có bằng nhau không. Nếu có, cả hai được bật và chương trình tiếp tục như bình thường. Nếu không, chúng ta xóa cả hai ngăn xếp (để dừng vòng lặp) và đẩy một ngăn lên ngăn xếp thay thế. Đây thực chất là một tuyên bố "phá vỡ".

  • Sau khi kiểm tra 8 loại khung, chúng tôi đẩy giá trị này chạy qua vòng lặp. Vì chúng tôi loại bỏ hầu hết trong số đó, các đoạn duy nhất có bất kỳ giá trị nào là các điều kiện khi chúng tôi so sánh với dấu ngoặc. Vì vậy, nếu bất kỳ dấu ngoặc nào được khớp, toàn bộ vòng lặp có giá trị là 1. Nếu không có giá trị nào trong số đó, toàn bộ vòng lặp có giá trị 0. Trong trường hợp này, chúng tôi sẽ xóa cả hai ngăn xếp và đẩy 0 lên ngăn xếp thay thế. Một lần nữa, đây giống như một tuyên bố "phá vỡ".

Sau khi vòng lặp chính này chạy, phần còn lại khá đơn giản. Chúng tôi đang ở trên ngăn xếp chính (trống) và ngăn xếp thay thế trống (nếu dấu ngoặc được khớp) hoặc không trống nếu chúng không có. Vì vậy, chúng tôi chạy này:

#Toggle to the alternate stack
<>

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

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

Điều này sẽ đẩy 0 hoặc 1 lên ngăn xếp chính và khi chương trình kết thúc, nó được in ngầm.


  • Cảm ơn @WheatWizard đã đưa ra một đoạn trích "stack" sạch và "logic không hợp lý" và thường xuyên cập nhật wiki github với các ví dụ hữu ích.

  • Cảm ơn chỉ @ ASCII vì đã viết một metagolfer số nguyên trực tuyến đã giúp ích rất nhiều trong việc viết chương trình này


sửa đổi

  • Loại bỏ một số dư thừa pop pop

  • Thay đổi logic không truy cập của tôi


1
Awwwwwweeeeesommmmeeeee!
Arjun

23

Brain-Flak , 204 196 190 byte

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

Hãy thử trực tuyến!

-8 byte nhờ Wheat Wizard. -6 byte nhờ Jo King.

Giải trình

Chương trình này lưu trữ mã ký tự của tất cả các dấu ngoặc không hiện tại trên ngăn xếp thứ hai. Các cặp khung <>, []{}mỗi người đều có mã số nhân vật mà khác biệt bởi chính xác 2, vì vậy không có cần phải kiểm tra cho họ đặc biệt. Cặp này ()chỉ khác nhau 1, vì vậy chúng tôi kiểm tra (cụ thể và giảm hiệu quả byte đó (thực sự tăng từng byte khác) trước khi tiếp tục.

# 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
<>((){[()]<>})

"logic không khác biệt" (còn được gọi là bằng) có thể ngắn hơn là([{}]<>({}))((){[()](<{}>)}{})
Wheat Wizard

Tôi nghĩ bạn có thể thay thế kiểm tra cuối cùng bằng ({<>[()]}())-6 byte
Jo King

@JoKing Cảm ơn. Tôi không nghĩ rằng tôi đã từng phát hiện ra điều đó.
Nitrodon

Vâng, tôi đã tìm ra nó trong câu trả lời của riêng tôi và nhận ra nó cũng có thể áp dụng cho bạn
Jo King

13

JavaScript (ES6), 52 50 byte

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

Liên tục xóa dấu ngoặc cho đến khi kết quả giống với bản gốc, sau đó trả về false trừ khi chuỗi này trống.

Chỉnh sửa: Đã lưu 2 byte nhờ @ edc65.



11

CJam, 25 24 23 21 byte

Cảm ơn Sp3000 đã lưu 2 byte.
Cảm ơn jimmy23013 vì đã lưu 2 byte.

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

Bộ thử nghiệm.

Làm việc về cơ bản giống như các câu trả lời khác: chúng tôi liên tục loại bỏ (), [], <>{}từ chuỗi và kiểm tra xem chúng tôi kết thúc với chuỗi rỗng. Để tránh phải kiểm tra khi chúng tôi hoàn thành, chúng tôi xóa các cặp Nthời gian có Nđộ dài của chuỗi, luôn luôn đủ (vì mỗi lần lặp sẽ xóa ít nhất hai ký tự, trừ khi chúng tôi hoàn thành). Tôi rất vui khi thấy điều này không đánh bại Retina. :) (Mặc dù Pyth hoặc Jelly có thể ...)

Có một mẹo chơi gôn thú vị ở đây: để có được chuỗi ()<>[]{}chúng tôi sử dụng như sau:

{()<>}a`$

, {()<>}Chỉ là một khối (tức là một hàm), chứa các dấu ngoặc khác dưới dạng mã. Với achúng tôi bọc khối trong một mảng. Việc `xâu chuỗi mảng đó, đưa ra "[{()<>}]". Cuối cùng, chúng tôi sắp xếp chuỗi với $, sắp xếp lại các dấu ngoặc ()<>[]{}.


Tôi không quen thuộc với ngôn ngữ của bạn, nhưng mô tả về thủ thuật đánh gôn của bạn làm cho âm thanh giống như ()<>[]{}`hoạt động tốt, và có cùng số byte, phải không?
Vịt Mooing

1
@MooingDuck Không bởi vì ()<>có bốn toán tử (giảm, tăng, rồi so sánh hoặc cắt bớt tùy thuộc vào toán hạng), sẽ được thực thi ngay lập tức, trong khi {}biểu thị một khối (tương đương với hàm của CJam), tức là một đoạn mã vừa được đẩy lên ngăn xếp mà không đánh giá nó ngay lập tức. Đó là lý do tại sao tôi cần {}phải bọc ()<>, nhưng sau đó sử dụng ađể đặt mọi thứ vào một mảng thì ngắn hơn [...].
Martin Ender

10

Python, 67 byte

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

Tạo và loại bỏ một biểu thức trông giống như

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

và kiểm tra nếu kết quả là trống rỗng.

Sp3000 đã lưu 8 byte bằng cách chỉ ra rằng [],(),{}có thể được nhấn chìm mà không có dấu ngoặc kép vì chúng là các đối tượng Python và hai parens là không cần thiết.


8

Yacc, 119 byte

Không sử dụng regex / thay thế.

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

Ung dung

%%                              # 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(){}

Biên soạn

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

Sử dụng

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

7

Pyth, 31 25 24 byte

Đã giảm xuống còn 25 byte nhờ FryAmTheEggMan Đã xóa 1 byte

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

Dùng thử tại đây: Bộ thử nghiệm !

Tôi vẫn là một người mới Pyth, bất kỳ trợ giúp đều được đánh giá cao.

Giải trình

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

BTW, xin chúc mừng câu trả lời Pyth khác (hiện là 20 byte)


Chào mừng bạn đến với Câu đố lập trình và Code Golf!
Ad Nam

@Ad Nam Cảm ơn bạn! Đây là sân golf đầu tiên của tôi!
FliiFe

Sân golf đầu tiên tốt đẹp! Với một số sắp xếp lại và công cụ, bạn có thể nhận được đến 25 : Vz=:z"<>|\[]|{}|\(\)"k;!z. Đặc biệt lưu ý, về cơ bản, bạn không bao giờ cần sử dụng lnếu bạn không thực sự cần số đó và =tự động đoán biến đầu tiên được sử dụng trong một biểu thức. Hãy cho tôi biết nếu bạn muốn tôi giải thích bất cứ điều gì khác trong phòng chat Pyth :)
FryAmTheEggman

@FryAmTheEggman Cảm ơn! Tôi không biết llà không cần thiết, đó là điều tốt để biết. Lúc đầu, tôi đã khai báo một hàm vì logic của tôi khác và quên xóa nó. Tôi sẽ bao gồm câu trả lời của bạn cho tôi? (Tôi là người mới>. <)
FliiFe

3
Nói chung, nếu nó được đăng trong một bình luận thì tác giả bình luận muốn bạn sử dụng nó. Vì vậy, đi ngay phía trước! :)
FryAmTheEggman

6

Bình thường, 20 byte

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

Dùng thử trực tuyến: Test Suite

Liên tục loại bỏ sự xuất hiện của [], (), <>{}bằng cách tách và tái sáp nhập. Kiểm tra xem chuỗi kết quả có trống hay không.


4

Javascript ES6, 54 byte

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

Sử dụng một thực hiện thay thế đệ quy. Đủ đơn giản.



4

Perl, 34 33 byte

Bao gồm +2 cho -lp

Chạy với đầu vào trên STDIN:

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

brackets.pl:

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

Tìm cặp ngoặc đầu tiên mà không có bất cứ thứ gì giữa chúng và loại bỏ nó miễn là có bất kỳ. Sau đó kiểm tra xem chuỗi cuối cùng có trống không.


Sẽ không s/\(\)|\[]|<>|{}//&&redo;$_=!$_làm việc? :)
Dada

Sẽ thật tuyệt nếu bạn cũng có thể giải thích.
Pokhriyal Prashant

@Dada Tất nhiên rồi. Tôi chắc chắn sẽ bị lão hóa ..
TonMedel

4

Brain-Flak , 204 byte

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

Hãy thử trực tuyến!

Không hoàn toàn ngắn như câu trả lời của Nitroden , nhưng sử dụng một cách tiếp cận rất khác. Cái này chạy qua đầu vào nhiều lần, loại bỏ các cặp dấu ngoặc phù hợp lân cận mỗi lần cho đến khi không còn dấu nào. Tại thời điểm đó nếu có bất cứ thứ gì còn lại trên ngăn xếp, thì chuỗi không được khớp hoàn toàn.

Giải trình:

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

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

Định dạng:

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

Mong đợi đầu vào mà không có một dòng mới. In \x00sai và \x01đúng.

Hãy thử trực tuyến.

Cách tiếp cận: Duy trì ngăn xếp bắt đầu bằng \x01và đẩy khung đóng tương ứng bất cứ khi nào gặp khung mở. Trước khi kiểm tra xem ký tự hiện tại có phải là dấu ngoặc mở hay không, trước tiên hãy kiểm tra xem nó có bằng dấu đóng ở đầu ngăn xếp hay không và liệu có bật nó không. Nếu đó không phải là khung đóng thích hợp cũng không phải là khung mở, hãy tiêu thụ phần còn lại của đầu vào trong khi di chuyển con trỏ sang phải. Cuối cùng, kiểm tra xem con trỏ bên cạnh chữ cái đầu tiên \x01.


2

Grime v0.1, 34 byte

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

In 1cho một trận đấu và 0không có trận đấu. Hãy thử trực tuyến!

Giải trình

Grime là ngôn ngữ phù hợp với mô hình 2D của tôi được thiết kế cho thử thách này ; nó cũng có thể được sử dụng để khớp với các chuỗi 1D. Đây là câu trả lời đầu tiên của tôi với nó. Tôi đã sửa đổi Grime ngày hôm nay, nhưng chỉ để thay đổi ký tự của một yếu tố cú pháp ( `thay vì ,), vì vậy nó không ảnh hưởng đến điểm số của tôi.

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 byte, không lọc

Hãy thử nó ở đây!

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/

Có thêm một chút chơi golf để thực hiện, nhưng ít nhất nó cũng hoạt động. Tôi đã thêm một lệnh ðđể theo dõi các ngăn xếp sau thử thách này để điều này có thể được thực hiện / dễ dàng từ xa. Tôi sẽ giải thích điều này một chút, nhưng nó thường theo dõi tất cả các chuỗi được lặp đi lặp lại và tìm kiếm sự lặp lại; nếu có lặp lại, thì chuỗi là không thể sửa chữa. Nếu không, chuỗi sẽ được giảm xuống chuỗi / ngăn trống và sẽ xuất ra 1. Nếu không, không có đầu ra sẽ được sản xuất.


2

PowerShell v2 +, 63 62 byte

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

Không thể bắt được JavaScript, nhưng hiện đang vượt qua các non-esolang khác.

Tiếp cận tương tự như câu trả lời khác: một vòng lặp đơn giản mà vẫn tiếp tục chừng nào chúng ta có thể loại bỏ một trong [], ()hoặc <>(với một số nhân vật không liên quan bởi vì chúng ta cần phải thoát khỏi các sản phẩm đặc biệt regex). Chúng tôi sử dụng $bnhư một người trợ giúp trên đường đi để nhớ những gì vòng lặp trước của chúng tôi $ađược đặt là. Một biến chưa được khởi tạo là $null, vì vậy lần đầu tiên gặp vòng lặp, $arõ ràng là không bằng $null.

Ở cuối vòng lặp, $acó trống hay không và Boolean-không phải của chuỗi đó là Truehoặc False.

Thí dụ

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 byte

Đã cạo 8 byte nhờ @xsot!

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

Sử dụng một ngăn xếp.


Tôi thích c%7&2. Thật ra, bạn không cần k. Thay vào đó, bạn có thể chỉ cần tăng inơi bạn sẽ sửa đổi kvì dù sao bạn cũng cần kiểm tra xem icó bằng không không. Một cái gì đó như thế này (mã chưa được kiểm tra) : 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 - Tôi sẽ tăng? Chúng ta cũng cần tránh đăng ký mảng với giá trị âm, vì vậy chúng ta phải kiểm tra i hoặc k trong for.
mIllIbyte

Ah tôi thấy. Vẫn còn chỗ để cải thiện: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 - Cảm ơn bạn! Để tổng hợp các khoản tiết kiệm, hãy đọc 5 byte đã lưu, ^ đã lưu một và toán hạng giữa của toán tử điều kiện đã lưu 2. Tôi ngạc nhiên rằng toán hạng giữa của toán tử điều kiện có thể là một phép gán. Tôi nghĩ rằng sẽ có một lỗi, một cái gì đó như "mất tích: trước =".
mIllIbyte

@xsot - Tôi đã thử tăng i thay vì sử dụng k, như lần đầu tiên bạn đề xuất: 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);}Nhưng điều này chưa hoạt động đối với đầu vào như thế ())), vì "popping" từ ngăn xếp không thực sự bằng 0 các giá trị trong mảng.
mIllIbyte

2

Java 7, 156 151 byte

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());}}

Tôi không mong đợi điều này sẽ giành được bất kỳ giải thưởng nào nhưng tôi chưa thấy câu trả lời Java. Ngoài ra, tôi muốn ẩn giấu xung quanh PPCG và tôi rất thích có thể bỏ phiếu / nhận xét về các câu trả lời khác.

Đầu vào được đưa ra dưới dạng tham số chương trình. Điều này tuân theo định dạng giống như nhiều câu trả lời khác ở đây ở chỗ nó tạo ra sự thay thế regex trong một vòng lặp. Ban đầu tôi có vòng lặp N lần trong đó N là độ dài của chuỗi gốc nhưng vòng lặp lại Integer.MAX_VALUEngắn hơn:]. Điều này sẽ ổn vì Integer.MAX_VALUEđộ dài tối đa của StringJava là do đó có một giả định ngầm định rằng độ dài của đầu vào là thứ có thể xử lý bằng Java. Thời gian chạy khá tệ (mất khoảng 20 phút trên lappytop của tôi) trên tài khoản của vòng lặp nhưng tôi không thấy bất kỳ hạn chế nào về điều đó.


2

Haskell , 151 byte

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

Hãy thử trực tuyến!


Một vài điều: Vì hàm (#)cần được gọi với chuỗi rỗng là đối số thứ hai, bạn cần tính (#"")vào số byte của mình. Cũng chỉ TrueFalseđược coi là trung thực / giả dối, xem Hướng dẫn về Luật chơi gôn .
Laikoni

1
Tuy nhiên, bốn dòng có dấu ngoặc đơn đóng có thể được thay thế bằng cách a:x#b:y|a==b=x#yđưa các byte xuống còn 113: Hãy thử trực tuyến!
Laikoni



1

Python 2, 80 byte

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

1

Julia, 51 byte

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

Ít điên rồ nhất của một số tùy chọn. Không có gì đáng ngạc nhiên, tận dụng sức mạnh của regex là con đường ngắn nhất để khớp chuỗi, nhưng điều này thực sự chỉ áp dụng nếu mẫu phù hợp là thường xuyên. Cố gắng thực hiện các mẫu đệ quy PCRE kết thúc bằng cách tăng kích thước của mã, bằng cách xem liệu toàn bộ chuỗi có khớp hay không bằng cách neo các đầu và sau đó tạo cấu trúc để chỉ định thân bên trong cho đệ quy regex. Không phải cái nào cũng đẹp hay có lợi cho việc đánh gôn.

Giải trình:

~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

Hàm này liên tục loại bỏ các cặp ngoặc đơn liền kề khỏi đối số duy nhất của nó và trả về true nếu nó có thể rút ra một chuỗi rỗng theo cách này.


1

sed, 39 36 byte (34 cho mã, 2 cho -r)

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

Hãy thử trực tuyến!

phiên bản sed của những gì dường như là cách tiếp cận tiêu chuẩn. Yêu cầu biểu thức chính quy mở rộng ( sed -r)

Đã lưu 3 byte nhờ quẻ bò


Bạn có thể xóa ais :atađể lưu byte
Kritixi Lithos

@KritixiLithos Rõ ràng đó là một lỗi trong GNU sed đã bị xóa trong 4.3 . Tôi có thể bỏ các nhân vật đó nếu mục này đủ gần với nhà lãnh đạo để nó có cơ hội chiến thắng, nhưng vì không phải vậy, tôi sẽ để nó ở dạng di động hơn để nó không ngừng hoạt động khi nhiều hệ thống nâng cấp lên 4.3.
Ray

1
Nhìn lại này, tôi chắc chắn rằng bạn có thể thả qtừ /./và thả các niềng răng có quá. Hãy thử trực tuyến! Điều này là do cách thức choạt động của
hange

@Cowsquack Cảm ơn. Đã chỉnh sửa.
Ray

0

05AB1E, 9 byte

žu2ôõ:g2Q

Đầu vào được đưa ra trong dấu ngoặc kép.

Hãy thử trực tuyến!

Giải trình:

ž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 byte

Dài hơn cả câu trả lời của C và 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)

Không sử dụng regex, thay vào đó sử dụng ký tự đầu tiên để xác định thẻ đóng là gì và tìm chỉ mục đầu tiên trong đó khung đó được cân bằng (tổng tích lũy bằng 0). Sau đó lặp lại kiểm tra xem những gì trong ngoặc và sau ngoặc là hợp lệ.

Phải xem có cách tiếp cận nào tốt hơn không ...


0

Lua , 295 byte

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

Phiên bản Ungolfed

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

Hãy thử trực tuyến!



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}

Cách tiếp cận ở đây là chuyển đổi chuỗi thành mã R, sau đó thử phân tích và đánh giá nó. Nếu điều đó cho một lỗi, sau đó trả lại FALSE.

Nhưng có một vấn đề nhỏ ... Các quy tắc của R cho ngoặc là khác nhau, vì vậy <> không phải là ngoặc và các loại khác có quy tắc riêng. Điều này được giải quyết bằng một cách tiếp cận mang tính cách mạng - một chức năng kêu rít, có chức năng duy nhất là báo hiệu lỗi nếu đầu và đuôi của nó rít lên theo những cách khác nhau.

Ví dụ: []được chuyển thành S('[', {}, ']'), trong đó S được định nghĩa là ...

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

Bởi vì đầu rít và đuôi rít phù hợp, không có lỗi được ném.

Một vài ví dụ khác (phần bên trái là một chuỗi dấu ngoặc và phần bên phải là phần chuyển đổi thành mã R hợp lệ có thể được đánh giá):

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

Một số chuỗi dấu ngoặc khác sẽ dẫn đến lỗi phân tích cú pháp:

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

Vì vậy, phần còn lại chỉ bắt lỗi và trả về SAI nếu có, và TRUE nếu không có.

Mã người dễ đọc:

 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?
   }

Áp dụng nó trên các trường hợp mẫu:

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 
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.