วงเล็บถูกจับคู่อย่างสมบูรณ์หรือไม่


56

คุณต้องเขียนโปรแกรมหรือฟังก์ชั่นที่รับสตริงของวงเล็บปีกกาและเอาท์พุทว่าสตริงนั้นตรงกันหรือไม่ โปรแกรมของคุณควรพิมพ์truthy หรือ falsyคุ้มค่าและ 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.

ตามปกตินี่คือ code-golf ดังนั้นช่องโหว่มาตรฐานจะมีผลบังคับใช้และคำตอบที่สั้นที่สุดในหน่วยไบต์จะชนะ



7
หมายเหตุถึงผู้มีสิทธิเลือกตั้งใกล้ที่อาจเกิดขึ้น: ความท้าทายที่ฉันเชื่อมโยงยังรวมถึงลำดับความสำคัญสำหรับประเภทของตัวยึดดังนั้นจึงไม่สามารถซ้อนในลำดับตามอำเภอใจ ฉันคิดว่ามันทำให้แตกต่างกันอย่างเพียงพอ
Martin Ender

คือ[}การแข่งขัน? และถ้าไม่มันจะถูกยกเว้นโดยกฎเหล่านี้ที่ไหน?
user207421

2
@EJP ไม่ไม่ใช่ Each pair of brackets has the correct opening and closing bracket and in the right order.
DJMcMayhem

6
ฉันจะแก้ปัญหาแรกในวงเล็บ
leo

คำตอบ:


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

นี่เป็นส่วนที่ยุ่งยาก สิ่งนี้ดูเหมือนว่าใน pseudocode คือ:

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

1
เคยเป็นแบบนี้มาก่อนõหรือไม่?
Zacharý

@ Zacharýใช่ถูกต้องแล้ว
Adnan

33

Brain-Flak , 1101, 1085 , 981 bytes

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

ลองออนไลน์!

นี่คือ 980 ไบต์ของซอร์สโค้ดและ+1สำหรับ-aแฟล็กที่อนุญาตให้อินพุต ASCII (แต่เอาต์พุตทศนิยม)

นี่เป็นคำตอบที่ฉันอยากจะเขียนเป็นเวลานานมาก อย่างน้อย 6 เดือน ฉันรอที่จะโพสต์สิ่งนี้เพราะฉันรู้ว่าการตอบคำถามนี้จะยากเป็นพิเศษในสมอง แต่มันก็คุ้มค่าด้วยเหตุผลสำคัญอย่างหนึ่ง: ซอร์สโค้ดเองนั้นเป็นข้อมูลจริงซึ่งเป็นจุดรวมของภาษานี้เอง

และเมื่อฉันเขียนที่นี่คำถามนี้เป็นสิ่งที่เป็นแรงบันดาลใจให้ฉันเขียนสมอง

ไม่นานหลังจากที่ฉันเขียนวงเล็บถูกจับคู่อย่างสมบูรณ์หรือไม่ทำให้ฉันสงสัยว่าคุณสามารถจัดเก็บข้อมูลด้วยวงเล็บปีกกาที่จับคู่ได้เท่านั้น สิ่งหนึ่งที่โดดเด่นสำหรับฉันคือแม้ว่าคุณจะมีเพียง 4 อะตอมเท่านั้น

(){}[]<>

คุณมีข้อมูล 8 หน่วยที่จะถ่ายทอดได้เนื่องจากประเภทวงเล็บแต่ละประเภทอาจว่างเปล่าหรือมีวงเล็บอื่น ๆ อยู่ระหว่างซึ่งเป็นข้อมูลที่แตกต่างกันโดยพื้นฐาน ดังนั้นฉันตัดสินใจที่จะเขียนภาษาที่อนุญาตให้ใช้กับวงเล็บปีกกาที่ตรงกันเท่านั้นและในกรณีที่วงเล็บว่างถ่ายทอดสิ่งที่แตกต่างจากวงเล็บกับวงเล็บอื่น ๆ ที่อยู่ภายในพวกเขา

คำตอบนี้ใช้เวลาประมาณสองชั่วโมงในการเขียน ฉันจะยอมรับว่ามันเล่นกอล์ฟได้ไม่ดีนักส่วนใหญ่เป็นเพราะมีรหัสซ้ำหลายครั้งในวงเล็บแต่ละประเภท แต่ส่วนใหญ่ฉันประหลาดใจที่ฉันสามารถเขียนคำตอบได้ทั้งหมดโดยเฉพาะอย่างยิ่ง Brain-Flak นั้น

esolang แบบมินิมัลลิสต์ออกแบบมาให้เจ็บปวดต่อการใช้งาน

ฉันจะพยายามเล่นกอล์ฟในภายหลัง แต่ฉันต้องการเอามันออกไป

ฉันมีคำอธิบายโดยละเอียด แต่มีความยาวประมาณ 6,000 ตัวอักษรดังนั้นฉันคิดว่ามันจะเป็นการดีถ้าจะวางสิ่งทั้งปวงลงในคำตอบนี้ คุณสามารถอ่านมันได้ที่นี่ถ้าคุณต้องการ ฉันจะเพิ่มคำอธิบายสั้น ๆ ที่นี่

แนวคิดพื้นฐานคือเราทำซ้ำขั้นตอนต่อไปนี้สำหรับตัวละครทุกตัวในสแต็ก:

  • เราตรวจสอบอักขระแต่ละตัวเพื่อดูว่าตรงกับวงเล็บหรือไม่ หากเป็นวงเล็บเปิดเราจะส่งตัวเลขไปยังสแต็กอื่นตามการแมปต่อไปนี้:

    ( = 1
    < = 2
    [ = 3
    { = 4
    
  • จากนั้นเราตรวจสอบเพื่อดูว่ามันตรงกับวงเล็บปิดใด ๆ ถ้าเป็นเช่นนั้นเราจะกดหมายเลขที่เท่ากันลงบนสแต็กสำรองเช่นเดียวกับการเปิดวงเล็บ จากนั้นเราตรวจสอบว่าตัวเลขสองอันดับแรกมีค่าเท่ากันหรือไม่ หากเป็นเช่นนั้นการดึงทั้งสองและโปรแกรมจะดำเนินต่อไปตามปกติ หากไม่ใช่เราจะล้างทั้งสองสแต็ก (เพื่อหยุดการวนซ้ำ) และกดหนึ่งลงในสแต็กสำรอง นี่คือคำสั่ง "หยุด" เป็นหลัก

  • หลังจากตรวจสอบประเภทของฉากยึด 8 ประเภทแล้วเราจะผลักดันค่าของการวิ่งนี้ผ่านลูป เนื่องจากเราไม่มีส่วนใหญ่เลยส่วนย่อยเท่านั้นที่มีค่าใด ๆ เป็นเงื่อนไขเมื่อเราเปรียบเทียบกับวงเล็บ ดังนั้นหากวงเล็บถูกจับคู่ทั้งหมดลูปมีค่า 1 หากไม่มีพวกเขาทั้งหมดลูปทั้งหมดมีค่าเป็น 0 ในกรณีนี้เราจะล้างทั้งสแต็คและกด 0 ลงบนสแต็กสำรอง นี่เป็นเหมือนคำสั่ง "หยุด"

หลังจากวนรอบหลักนี้กำลังทำงานส่วนที่เหลือค่อนข้างง่าย เราอยู่ในสแต็กหลัก (ว่าง) และสแต็กทางเลือกนั้นว่างเปล่า (ถ้าวงเล็บถูกจับคู่) หรือไม่ว่างถ้ามันไม่ว่าง ดังนั้นเราจึงรันสิ่งนี้:

#Toggle to the alternate stack
<>

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

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

สิ่งนี้จะผลัก 0 หรือ 1 ไปยัง main-stack และเมื่อโปรแกรมสิ้นสุดลงโปรแกรมจะถูกพิมพ์โดยปริยาย


  • ขอบคุณ@WheatWizard ที่มาพร้อมกับ "สะอาด" สแต็กที่ดีและ "ตรรกะไม่ใช่" สนิปเพตที่ดีและสำหรับการอัปเดตวิกิ githubเป็นประจำด้วยตัวอย่างที่มีประโยชน์

  • ขอบคุณ@ ASCII- เท่านั้นสำหรับการเขียนmetagolfer จำนวนเต็มออนไลน์ซึ่งช่วยอย่างมากในการเขียนโปรแกรมนี้


การแก้ไข

  • ลบป๊อปที่ซ้ำซ้อนแบบพุชบางส่วนออก

  • เปลี่ยนลอจิกตัวนับศูนย์ของฉัน


1
Awwwwwweeeeesommmmeeeee!
Arjun

23

Brain-Flak , 204 196 190 ไบต์

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

ลองออนไลน์!

-8 ไบท์ขอบคุณข้าวสาลีวิซาร์ด -6 ไบต์ขอบคุณ Jo King

คำอธิบาย

โปรแกรมนี้จัดเก็บรหัสอักขระของวงเล็บเหลี่ยม unclosed ปัจจุบันทั้งหมดในกองซ้อนที่สอง คู่วงเล็บ<>, []และ{}แต่ละคนมีรหัสตัวอักษรที่แตกต่างกันโดยว่าที่ 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 Wizard

ฉันคิดว่าคุณสามารถแทนที่การตรวจสอบครั้งสุดท้ายด้วย({<>[()]}())-6 ไบต์
Jo King

@ โจกิ้งขอบคุณ ฉันไม่คิดว่าฉันจะได้เห็นว่า
Nitrodon

ใช่ฉันคิดออกมาในคำตอบของฉันเองและตระหนักว่ามันใช้ได้กับคุณเช่นกัน
โจคิง

13

JavaScript (ES6), 52 50 ไบต์

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

ลบวงเล็บซ้ำหลายครั้งจนกว่าผลลัพธ์จะเหมือนกับต้นฉบับจากนั้นส่งคืนค่าเท็จยกเว้นตอนนี้สตริงว่างเปล่า

แก้ไข: บันทึก 2 ไบต์ขอบคุณ @ edc65



11

CJam, 25 24 23 21 bytes

ขอบคุณ Sp3000 สำหรับการบันทึก 2 ไบต์
ขอบคุณ jimmy23013 สำหรับการบันทึก 2 ไบต์

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

ชุดทดสอบ

การทำงานหลักเช่นเดียวกับคำตอบอื่น ๆ : เราซ้ำแล้วซ้ำอีกลบ(), [], <>และ{}จากสตริงและตรวจสอบว่าเราจบลงด้วยสตริงที่ว่างเปล่า เพื่อหลีกเลี่ยงการตรวจสอบเมื่อเราทำเสร็จแล้วเราจะลบคู่Nครั้งที่Nความยาวของสตริงซึ่งเพียงพอเสมอ (เนื่องจากการทำซ้ำแต่ละครั้งจะลบอักขระอย่างน้อยสองตัวยกเว้นเราจะทำเสร็จ) ฉันดีใจที่เห็นว่าสิ่งนี้ไม่สามารถเอาชนะจอประสาทตาได้ :) (แม้ว่า Pyth หรือ Jelly อาจ ... )

มีเคล็ดลับการเล่นกอล์ฟที่นี่: เพื่อให้ได้สายที่()<>[]{}เราใช้ดังต่อไปนี้:

{()<>}a`$

The, {()<>}เป็นเพียงบล็อก (เช่นฟังก์ชั่น) ซึ่งมีวงเล็บอื่น ๆ เป็นรหัส เมื่อaเราตัดบล็อกในอาร์เรย์ `stringifies "[{()<>}]"อาร์เรย์ที่ซึ่งจะช่วยให้ สุดท้ายเราเรียงลำดับสตริงด้วยซึ่งจัดเรียงวงเล็บไป$()<>[]{}


ฉันไม่คุ้นเคยกับภาษาของคุณ แต่คำอธิบายเกี่ยวกับกลเม็ดการเล่นกอล์ฟของคุณทำให้ฟังดูเหมือน()<>[]{}`จะทำงานได้ดีและมีจำนวนไบต์เท่ากันใช่ไหม
Mooing Duck

1
@MooingDuck ไม่ใช่เพราะ()<>มีสี่ตัวดำเนินการ (ลดลงเพิ่มขึ้นแล้วเปรียบเทียบหรือตัดทอนขึ้นอยู่กับตัวถูกดำเนินการ) ซึ่งจะถูกดำเนินการทันทีในขณะที่{}หมายถึงบล็อก (เทียบเท่าฟังก์ชันของ CJam) คือชิ้นส่วนของรหัสที่เพิ่งผลัก ลงบนสแต็กโดยไม่ทำการประเมินทันที นั่นเป็นเหตุผลที่ฉันต้องการ{}ที่จะห่อ()และ<>แต่แล้วใช้สำหรับการวางทุกอย่างในอาร์เรย์จะสั้นกว่าa [...]
Martin Ender

10

Python ขนาด 67 ไบต์

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

สร้างและ evals นิพจน์ที่ดูเหมือน

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

และตรวจสอบว่าผลลัพธ์ว่างเปล่า

Sp3000 บันทึก 8 ไบต์โดยการชี้ให้เห็นว่า[],(),{}สามารถ subbed โดยไม่มีเครื่องหมายอัญประกาศเพราะพวกเขาเป็นวัตถุ Python และสอง parens ที่ไม่จำเป็น


8

Yacc, 119 ไบต์

ห้ามใช้ regex / replace

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

Ungolfed

%%                              # 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 ไบต์

ลดขนาดลงเหลือ 25 ไบต์ด้วย FryAmTheEggMan ลบออก 1 ไบต์

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

BTW ขอแสดงความยินดีกับคำตอบ Pyth อื่น ๆ (ซึ่งปัจจุบันคือ 20 ไบต์)


ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนาและรหัสกอล์ฟ!
Adnan

@Adnan ขอบคุณ! นี่คือสนามกอล์ฟครั้งแรกของฉัน!
FliiFe

กอล์ฟครั้งแรกที่ดี! ด้วยการจัดเรียงบางและสิ่งที่คุณจะได้รับ Vz=:z"<>|\[]|{}|\(\)"k;!z25: โดยเฉพาะอย่างยิ่งการจดบันทึกคุณไม่จำเป็นต้องใช้โดยทั่วไปlหากคุณไม่ต้องการตัวเลขจริง ๆ และ=คาดเดาตัวแปรแรกที่ใช้ในนิพจน์โดยอัตโนมัติ แจ้งให้เราทราบหากคุณต้องการให้ฉันอธิบายสิ่งอื่นในห้องสนทนา
Pyth

@FryAmTheEggman ขอบคุณ! ฉันไม่รู้ว่าlมันไม่จำเป็นเลย ตอนแรกฉันประกาศฟังก์ชั่นเพราะตรรกะของฉันแตกต่างกันและลืมที่จะลบมัน ฉันควรจะรวมคำตอบของคุณไว้กับฉันไหม? (ฉันเป็นมือใหม่>. <)
FliiFe

3
โดยทั่วไปหากมีการโพสต์ในความคิดเห็นผู้เขียนความคิดเห็นต้องการให้คุณใช้ ดังนั้นไปข้างหน้า! :)
FryAmTheEggman

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เป็นเท็จและ\x01เป็นจริง

ลองออนไลน์

วิธีการ: ดูแลรักษาสแต็กที่เริ่มต้นด้วย\x01และดันวงเล็บปิดที่สอดคล้องกันเมื่อใดก็ตามที่พบว่ามีวงเล็บเปิด ก่อนที่จะตรวจสอบว่าตัวละครปัจจุบันเป็นวงเล็บเปิดหรือไม่อันดับแรกให้ตรวจสอบว่ามันเท่ากับวงเล็บปิดที่ด้านบนของสแต็กหรือไม่ หากไม่ใช่วงเล็บปิดที่เหมาะสมหรือวงเล็บเปิดให้ใช้อินพุตที่เหลือในขณะที่เลื่อนตัวชี้ไปทางขวา \x01ในตอนท้ายตรวจสอบว่าตัวชี้เป็นไปเพื่อเริ่มต้น


2

Grime v0.1, 34 ไบต์

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

พิมพ์1สำหรับการแข่งขันและ0ไม่ตรงกัน ลองออนไลน์!

คำอธิบาย

สิ่งสกปรกเป็น 2D ภาษารูปแบบจับคู่ของฉันที่ออกแบบมาสำหรับความท้าทายนี้ ; มันยังสามารถใช้เพื่อจับคู่สตริง 1D นี่คือคำตอบแรกของฉันกับมัน ฉันทำการปรับเปลี่ยน 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 ได้ แต่ขณะนี้กำลังตัดขอบที่ไม่ใช่ esolangs อื่น ๆ

วิธีการที่คล้ายกันเป็นคำตอบอื่น ๆ : วงที่เรียบง่ายที่ยังคงตราบใดที่เราสามารถลบหนึ่ง[], ()หรือ<>(มีตัวละครหลายภายนอกเพราะเราต้องหนีพิเศษ regex) เราใช้$bเป็นผู้ช่วยตลอดทางเพื่อจดจำสิ่งที่วงก่อนหน้าของเรา$aตั้งไว้ ตัวแปรเตรียมเป็น$nullจึงเป็นครั้งแรกที่วงจะพบจะเห็นได้ชัดไม่เท่ากับ$a$null

ในตอนท้ายของวงที่$aเป็นทั้งที่ว่างเปล่าหรือไม่และบูลีนไม่ของสตริงที่เป็นอย่างใดอย่างหนึ่งหรือTrueFalse

ตัวอย่าง

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 ไบต์

โกนได้ 8 ไบต์ขอบคุณ @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);}

ใช้สแต็ก


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 - ฉันจะเพิ่มขึ้นหรือไม่ นอกจากนี้เรายังต้องหลีกเลี่ยงการห้อยอาร์เรย์ด้วยค่าลบดังนั้นเราต้องทดสอบ i หรือ k ในเครื่องหมาย for
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 ฉันประหลาดใจที่ตัวถูกดำเนินการตรงกลางของตัวดำเนินการตามเงื่อนไขสามารถกำหนดได้ ฉันคิดว่าจะมีข้อผิดพลาดบางอย่างเช่น "หายไป: 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);}แต่สิ่งนี้ยังใช้งานไม่ได้สำหรับอินพุตเช่น()))เนื่องจาก "popping" จากสแต็กไม่ได้มีค่าเป็นศูนย์ในอาร์เรย์
mIllIbyte

2

Java 7, 156 151 bytes

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

ฉันไม่ได้คาดหวังว่าสิ่งนี้จะได้รับรางวัลใด ๆ แต่ฉันยังไม่เห็นคำตอบของจาวา นอกจากนี้ฉันชอบที่จะแฝงตัวรอบ PPCG และฉันจะเพลิดเพลินไปกับความสามารถในการลงคะแนน / แสดงความคิดเห็นในคำตอบอื่น ๆ

อินพุตถูกกำหนดเป็นพารามิเตอร์โปรแกรม รูปแบบนี้เป็นไปตามรูปแบบเดียวกันกับคำตอบอื่น ๆ มากมายที่นี่ซึ่งเป็นการนำรูปแบบการทดแทน regex มาใช้ในการวนซ้ำ แต่เดิมฉันมีห่วงครั้ง N ที่ N คือความยาวของสตริงเดิม แต่วนรอบเพื่อInteger.MAX_VALUEสั้น:] สิ่งนี้ควรใช้ได้เนื่องจากInteger.MAX_VALUEเป็นความยาวสูงสุดของ a Stringใน Java ดังนั้นจึงมีข้อสันนิษฐานโดยนัยว่าความยาวของอินพุตเป็นสิ่งที่ Java สามารถจัดการได้ รันไทม์ค่อนข้างแย่ (ใช้เวลาประมาณ 20 นาทีบน lappytop ของฉัน) เนื่องจากการวนซ้ำ แต่ฉันไม่เห็นข้อ จำกัด ใด ๆ


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

ลองออนไลน์!


บางสิ่ง: เนื่องจากฟังก์ชัน(#)จะต้องถูกเรียกด้วยสตริงว่างเปล่าเป็นอาร์กิวเมนต์ที่สองคุณจะต้องนับจำนวน(#"")ต่อจำนวนไบต์ของคุณ นอกจากนี้เท่านั้นTrueและFalseได้รับการพิจารณา truthy / falsy ดูที่คู่มือกฎกอล์ฟ
Laikoni

1
อย่างไรก็ตามสามารถแทนที่สี่บรรทัดด้วยวงเล็บปิดa:x#b:y|a==b=x#yซึ่งทำให้ไบต์มีขนาดไม่เกิน 113: ลองออนไลน์!
Laikoni




1

จูเลีย 51 ไบต์

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

อย่างน้อยบ้าของตัวเลือกต่าง ๆ น่าแปลกใจที่การยกระดับพลังของ regex เป็นเส้นทางที่สั้นที่สุดในการจับคู่สตริง แต่สิ่งนี้จะใช้เฉพาะในกรณีที่รูปแบบการจับคู่เป็นปกติ การพยายามทำรูปแบบการวนซ้ำแบบ 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

ฟังก์ชั่นจะลบวงเล็บที่อยู่ติดกันออกจากอาร์กิวเมนต์เพียงตัวเดียวและส่งกลับค่าจริงถ้ามันสามารถรับสตริงที่ว่างได้ด้วยวิธีนี้


1

sed, 39 36 ไบต์ (34 สำหรับรหัส, 2 สำหรับ -r)

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

ลองออนไลน์!

รุ่น sed ของสิ่งที่ดูเหมือนจะเป็นวิธีการมาตรฐาน ต้องมีการแสดงออกปกติเพิ่มเติม ( sed -r)

บันทึกแล้ว 3 ไบต์ขอบคุณ Cows นักต้มตุ๋น


คุณสามารถลบais :aและtasave bytes ได้
Kritixi Lithos

@KritixiLithos เห็นได้ชัดว่าเป็นข้อผิดพลาดใน GNU sed ที่ถูกลบออกใน 4.3 ฉันอาจทิ้งตัวละครเหล่านั้นถ้ารายการนี้ใกล้กับผู้นำมากพอที่จะมีโอกาสชนะ แต่เนื่องจากไม่ใช่ฉันจะทิ้งมันไว้ในรูปแบบพกพามากขึ้นดังนั้นมันจึงไม่หยุดทำงาน เมื่อระบบอัปเกรดเป็น 4.3
เรย์

1
เมื่อมองย้อนกลับไปฉันมั่นใจว่าคุณสามารถดรอปqจาก/./และวงเล็บปีกกาที่นั่นด้วย ลองออนไลน์! นี่เป็นเพราะวิธีการcทำงานของ
แฮงค์

@Cowsquack ขอบคุณ แก้ไข
เรย์


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)

ไม่ใช้ regex ใช้อักขระตัวแรกเพื่อกำหนดว่าแท็กปิดคืออะไรและค้นหาดัชนีแรกที่วงเล็บนั้นมีความสมดุล (ผลรวมสะสมเป็นศูนย์) จากนั้นตรวจสอบซ้ำ ๆ ว่าสิ่งที่อยู่ในวงเล็บเหลี่ยมและหลังวงเล็บปีกกานั้นถูกต้อง

ต้องดูว่ามีวิธีการที่ดีกว่า ...


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 
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.