Чи повністю відповідають дужки?


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
Примітка для потенційних близьких виборців: Виклик, з яким я пов’язаний, також включає пріоритетний порядок для типів дужок, щоб вони не могли вкладатись у довільному порядку. Я думаю, що це робить його досить різним.
Мартін Ендер

Чи [}є сірник? А якщо ні, то де це виключено цими правилами?
користувач207421

2
@EJP Ні, це не так. Each pair of brackets has the correct opening and closing bracket and in the right order.
DJMcMayhem

6
Я upvote першого рішення в кронштейні
Лео

Відповіді:


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

1
Це раніше õбуло додано?
Zacharý

@ Zacharý Так, це правильно
Аднан

33

Мозг-Флак , 1101, 1085 , 981 байт

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

Спробуйте в Інтернеті!

Це 980 байт вихідного коду і +1для -aпрапора, що дозволяє вводити ASCII (але десятковий вихід)

Це відповідь, яку я хотів написати дуже давно. Не менше 6 місяців. Я зачекав, коли я опублікую це, тому що знав, що відповісти на цей виклик буде дуже важко в мозку. Але це варто з однієї дуже важливої ​​причини: вихідний код сам по собі є правдоподібним вкладом, який полягає у всьому суті цієї мови.

І коли я тут писав , саме це питання надихнуло мене написати мозку.

Незабаром після того, як я написав, чи повністю збігаються дужки ?, мене змусило задуматися, скільки інформації ви можете зберігати лише з відповідними дужками. Одне, що мені виділялося, було те, що навіть у вас є лише 4 "атоми":

(){}[]<>

у вас дійсно є 8 одиниць інформації для передачі, оскільки кожен з цих типів дужок може бути порожнім або мати між собою інші дужки, які є принципово різними фрагментами інформації. Отже, я вирішив написати мову, яка дозволена лише для відповідних дужок, і де порожні дужки містять щось інше, ніж дужки з іншими дужками всередині них.

На написання цієї відповіді було потрібно приблизно дві години. Я визнаю, що це досить погано гольф, в основному тому, що багато код повторюється для кожного типу дужок. Але я здебільшого вражений тим, що мені вдалося взагалі написати відповідь, особливо враховуючи, що це Мозг-Флак

Мінімалістський езоланг, розроблений так, щоб його було болісно використовувати

Я збираюся пізніше спробувати пограти в гольф, але я все-таки хотів отримати це.

У мене є детальне пояснення, але це близько 6 тисяч символів, тому я вважаю, що не було б розумно вставити всю річ у цю відповідь. Ви можете прочитати його тут, якщо хочете. Я додам тут коротше пояснення.

Основна ідея полягає в тому, що ми повторюємо наступні кроки для кожного символу в стеку:

  • Ми перевіряємо кожен символ, щоб побачити, чи відповідає він будь-якій дужці. Якщо це відкривна дужка, ми натискаємо число на інший стек відповідно до наступного відображення:

    ( = 1
    < = 2
    [ = 3
    { = 4
    
  • Потім ми перевіряємо, чи відповідає вона будь-якій дужці. Якщо це так, ми натискаємо еквівалентне число на альтернативний стек, як і для відкриття дужок. Потім перевіряємо, чи рівні два топ-числа. Якщо вони є, обидва вискакують, і програма продовжується як завжди. Якщо їх немає, ми очищаємо обидві стеки (для припинення циклу) і натискаємо один на альтернативний стек. Це по суті заява про "перерву".

  • Перевіривши 8 типів дужок, ми просуваємо значення цього пробігу через цикл. Оскільки ми звели нуль на більшу частину цього, єдиними фрагментами, які мають будь-яке значення, є умови, коли ми порівнюємо їх з дужками. Отже, якщо будь-яка дужка збігається, цілий цикл має значення 1. Якщо жоден з них не зробив, цілий цикл має значення 0. У цьому випадку ми очистимо обидві стеки та натиснемо 0 на альтернативний стек. Знову ж таки, це як заява про "перерву".

Після запуску цієї основної петлі, решта досить проста. Ми знаходимось у (порожньому) головному стеку, а альтернативний стек порожній (якщо дужки були зіставлені) або не порожній, якщо їх не було. Отже, ми виконуємо це:

#Toggle to the alternate stack
<>

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

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

Це натисне 0 або 1 на основний стек, і коли програма закінчується, вона неявно друкується.


  • Завдяки @WheatWizard придумав хороший фрагмент "рівний" та "логічний не" фрагмент, а також за регулярне оновлення вікі github на корисних прикладах.

  • Завдяки @ ASCII лише для написання цілого онлайн- метагольфера, який надзвичайно допоміг у написанні цієї програми


доопрацювання

  • Видалено кілька надмірностей push push

  • Змінилася моя логіка нульового лічильника


1
Awwwwwweeeeesommmmeeeee!
Арджун

23

Мозг-Флак , 204 196 190 байт

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

Спробуйте в Інтернеті!

-8 байт завдяки пшеничному майстру. -6 байт завдяки Джо Кінгу.

Пояснення

Ця програма зберігає коди символів усіх поточних незакритих дужок на другому стеку. Пари дужок <>, []і {}мають коди символів , які відрізняються рівно 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
<>((){[()]<>})

"Логічна не різниця" (також відома як рівна) може бути коротшою як([{}]<>({}))((){[()](<{}>)}{})
Пшеничний майстер

Я думаю, ви можете замінити цю останню перевірку ({<>[()]}())на -6 байт
Jo King

@JoKing Дякую Я не думаю, що я ніколи цього не помітив.
Нітродон

Так, я зрозумів це у власній відповіді і зрозумів, що це стосується і твоїх
Джо Кінг,

13

JavaScript (ES6), 52 50 байт

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

Неодноразово видаляйте дужки, поки результат не буде таким, як оригінал, а потім поверніть помилкове, якщо рядок тепер не порожній.

Редагувати: збережено 2 байти завдяки @ edc65.



11

CJam, 25 24 23 21 байт

Завдяки Sp3000 за збереження 2 байт.
Завдяки jimmy23013 за збереження 2 байт.

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

Тестовий набір.

Працює в основному так само , як інші відповіді: ми неодноразово видалити (), [], <>і {}з рядка, щоб переглянути , якщо ми в кінцевому підсумку з нового рядка. Щоб уникнути необхідності перевіряти, коли ми закінчили, ми видаляємо пари Nразів, де Nдовжина рядка, що завжди достатньо (оскільки кожна ітерація видалить щонайменше два символи, якщо це не зроблено). Я радий бачити, що це не перемагає Сітківку. :) (Хоча Pyth або Jelly можуть ...)

Тут є один цікавий трюк з гольфу: для отримання нитки ()<>[]{}ми використовуємо наступне:

{()<>}a`$

The {()<>}- просто блок (тобто функція), який містить інші дужки як код. За допомогою aми загортаємо блок в масив. У `stringifies , що масив, який дає "[{()<>}]". Нарешті, ми сортуємо рядок, за допомогою $якого переставляємо дужки ()<>[]{}.


Я не знайомий з вашою мовою, але ваш опис трюку з гольфу дозволяє здатися, що він ()<>[]{}`би працював так само добре, і був би стільки ж байтів, правда?
Mooing Duck

1
@MooingDuck Ні, тому що ()<>чотири оператори (декремент, приріст, а потім порівняння або укорочення залежно від операндів), які будуть виконуватися негайно, тоді як {}позначає блок (еквівалент функції CJam функції), тобто фрагмент коду, який щойно натиснув на стек, не оцінюючи його негайно. Ось чому мені потрібно {}обернути ()і <>, але використовувати aдля розміщення всього в масив коротше, ніж [...].
Мартін Ендер

10

Пітон, 67 байт

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

Породжує і оцінює вираз, який виглядає так

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

і перевіряє, чи результат порожній.

Sp3000 врятував 8 байт, вказавши на те, що вони [],(),{}можуть бути підпункти без лапок, оскільки вони об'єкти Python, і що два парени були непотрібні.


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 байти

Поле за полегшенням до 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 Дякую! Це мій перший гольф!
FliiFe

Гарний перший гольф! З деякими перебудовуючи та інше, ви можете отримати до 25: Vz=:z"<>|\[]|{}|\(\)"k;!z. Зокрема, зауважимо, що ви взагалі ніколи не потребуєте використання, lякщо вам насправді не потрібне число, і =автоматично вгадуєте першу змінну, використану в виразі. Дайте мені знати, чи хочете ви мені пояснити що-небудь ще в чаті Pyth :)
FryAmTheEggman

@FryAmTheEggman Дякую! Я не знав l, що це зайве, це добре знати. Спочатку я оголосив функцію, оскільки моя логіка була іншою, і забув її видалити. Чи повинен я включити вашу відповідь до своєї? (Я новачок>. <)
FliiFe

3
Як правило, якщо він розміщений у коментарі, то автор коментаря хоче, щоб ви його використовували. Тож ідіть прямо вперед! :)
FryAmTheEggman

6

Pyth, 20 байт

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

Спробуйте в Інтернеті: Test Suite

Багаторазово видаляє входжень [], (), <>і {}шляхом розщеплення і повторного об'єднання. Перевіряє чи порожній рядок порожній чи ні.


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 Звичайно. Я, мабуть, старечий ..
Тон Євангелія

4

Мозок-Флак , 204 байти

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

Спробуйте в Інтернеті!

Не зовсім короткий, як відповідь Нітродена , але використовує зовсім інший підхід. Цей проходить через вхід кілька разів, видаляючи сусідні пари дужок щоразу, поки не залишиться жодного. У той момент, якщо в стеку залишилося щось, то рядок не повністю відповідає.

Пояснення:

(())  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без збігу. Спробуйте в Інтернеті!

Пояснення

Grime - моя 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, але наразі обробляє інші не езоланги.

Подібний підхід , як і інші відповіді: простий цикл , який триває до тих пір , поки ми можемо видалити один з [], (), або <>(з декількома сторонніми символами , тому що нам потрібно , щоб уникнути регулярних виразів спеціальні). Ми використовуємо $bяк помічник, щоб пам’ятати, що $aбуло встановлено нашим попереднім циклом . Неініціалізована змінна є $null, тому перший раз, коли цикл зустрічається, $aявно не дорівнює $null.

В кінці циклу, $aабо порожньо , або ні, і булева- а не тієї рядки або Trueабо 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 байт

Поголений з 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 в.
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. Я здивований, що середній операнд умовного оператора може бути призначенням. Я думав, що буде помилка, щось на кшталт "відсутнє: раніше =".
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- коротший:]. Це має бути нормально, оскільки Integer.MAX_VALUEце максимальна довжина Stringв Java, тому існує неявне припущення, що довжина вводу - це те, що 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

Спробуйте в Інтернеті!


Кілька речей: Оскільки функцію (#)потрібно викликати порожнім рядком як другим аргументом, вам потрібно порахувати кількість (#"")байтів. Крім того, тільки Trueі Falseвважається truthy / falsy см Керівництва по Golfing правилам .
Лайконі

1
Однак чотири рядки із дужками, що закриваються, можна замінити a:x#b:y|a==b=x#y, знизивши байти до 113: Спробуйте це в Інтернеті!
Лайконі


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 закінчується на повітряній кулі розміром коду, або бачачи, чи відповідає цілий рядок, або закріплюючи кінці, а потім створюючи конструкцію, щоб вказати внутрішнє тіло для регексу регексу. Жоден з яких не є гарним або сприятливим для кодування гольфу.

Пояснення:

~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 для коду, 2 для -r)

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

Спробуйте в Інтернеті!

sed версія того, що здається стандартним підходом. Потрібні розширені регулярні вирази ( sed -r)

Збережено 3 байти завдяки кряканню корів


Ви можете видалити aIS :aі taврятувати байти
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)

Не використовує регулярний вираз, натомість використовує перший символ, щоб визначити, що таке тег завершення, і знаходить перший індекс, де ця дужка збалансована (сукупна сума дорівнює нулю). Потім ітеративно перевіряє, що те, що знаходиться в дужках та після дужок, є дійсним.

Треба подивитися, чи є кращий підхід ...


0

Луа , 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('[',{},'('); 

Таким чином, частина, яка залишилася, просто вловлює помилки та повертає ЛІЖНЕ, якщо такі є, і ПРАВИЛЬНІ, якщо таких немає.

Код, прочитаний людиною:

 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 
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.