Скобки полностью совпадают?

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.

Как обычно, это код-гольф, поэтому применяются стандартные лазейки, и выигрывает кратчайший ответ в байтах.

DJMcMayhem
источник
1
Связанный.
Мартин Эндер
7
Примечание для потенциальных близких избирателей: Задача, которую я связал, также включает порядок приоритетов для типов скобок, поэтому они не могут быть вложены в произвольном порядке. Я думаю, что это делает его достаточно другим.
Мартин Эндер
Это [}совпадение? И если нет, то где это исключено этими правилами?
user207421
2
@ EJP Нет, это не так. Each pair of brackets has the correct opening and closing bracket and in the right order.
DJMcMayhem
6
Я опишу первое решение в скобках
Лев

Ответы:

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ý Да, это правильно
Аднан,
33

Brain-Flak , 1101, 1085 , 981 байт

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

Попробуйте онлайн!

Это 980 байт исходного кода, и +1для -aфлага, допускающего ввод ASCII (но десятичный вывод)

Это ответ , который я давно хотел написать для очень и очень долго. Не менее 6 месяцев. Я ждал, чтобы опубликовать это, потому что я знал, что ответить на этот вызов будет очень сложно в мозгу. Но оно того стоит по одной очень важной причине: исходный код сам по себе является правдоподобным вводом, который и составляет весь смысл самого этого языка.

И как я уже писал здесь , этот вопрос вдохновил меня на написание мозгов.

Вскоре после того, как я написал «Соответствуют ли скобки?», Я задался вопросом, сколько информации можно хранить только с соответствующими скобками. Одна вещь, которая выделялась для меня, состояла в том, что, хотя у вас есть только 4 вида атомов:

(){}[]<>

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

Этот ответ занял примерно два часа, чтобы написать. Я признаю, что это довольно плохо, в основном потому, что большая часть кода повторяется для каждого типа скобок. Но я больше всего удивлен, что мне вообще удалось написать ответ, особенно учитывая, что Brain-Flak

Минималистский esolang, разработанный, чтобы быть болезненным, чтобы использовать

Я собираюсь попытаться сыграть в гольф позже, но я все равно хотел это сделать.

У меня есть подробное объяснение, но оно имеет длину около 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 в основной стек, а когда программа завершится, она будет напечатана неявно.



изменения

  • Удалена некоторая избыточность всплывающих окон

  • Изменилась логика счетчика нуля

DJMcMayhem
источник
1
Awwwwwweeeeesommmmeeeee!
Арджун,
23

Brain-Flak , 204 196 190 байтов

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

Попробуйте онлайн!

-8 байт благодаря Wheat Wizard. -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
<>((){[()]<>})
Nitrodon
источник
"логическое различие" (также известное как равно) может быть короче, как([{}]<>({}))((){[()](<{}>)}{})
Wheat Wizard
Я думаю, что вы можете заменить эту последнюю проверку ({<>[()]}())на -6 байт
Джо Кинг,
@ JoKing Спасибо. Я не думаю, что когда-либо заметил бы это.
Nitrodon
Да, я понял это в своем собственном ответе и понял, что это применимо и к твоему
Джо Кинг,
13

JavaScript (ES6), 52 50 байт

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

Повторно снимайте скобки, пока результат не станет таким же, как в оригинале, а затем верните false, если строка не пуста.

Редактировать: 2 байта сохранены благодаря @ edc65.

Нил
источник
11

CJam, 25 24 23 21 байт

Спасибо Sp3000 за сохранение 2 байта.
Спасибо jimmy23013 за сохранение 2 байта.

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

Тестирование.

Работает в основном так же , как другие ответы: мы неоднократно удалить (), [], <>и {}из строки и проверить , если мы в конечном итоге с пустой строкой. Чтобы не проверять, когда мы закончим, мы удаляем пары Nвремен, где Nесть длина строки, которая всегда достаточна (поскольку каждая итерация удалит как минимум два символа, если мы не закончили). Я рад видеть, что это не побеждает Retina. :) (хотя Pyth или Jelly могли бы ...)

Здесь есть одна забавная игра в гольф: чтобы получить строку, ()<>[]{}мы используем следующее:

{()<>}a`$

Это {()<>}просто блок (то есть функция), который содержит другие скобки в виде кода. При этом aмы оборачиваем блок в массив. `Stringifies этого массива, который дает "[{()<>}]". Наконец, мы сортируем строку с $, которая переставляет скобки в ()<>[]{}.

Мартин Эндер
источник
Я не знаком с вашим языком, но ваше описание вашего трюка в гольфе заставляет его звучать так, как будто оно ()<>[]{}`будет работать так же хорошо, и иметь такое же количество байтов, верно?
Mooing Duck
1
@MooingDuck Нет, потому что ()<>это четыре оператора (декремент, инкремент, а затем сравнение или усечение в зависимости от операндов), которые будут выполняться немедленно, тогда как {}обозначает блок (эквивалент функции CJam), то есть фрагмент кода, который просто выдвигается в стек, не оценивая его сразу. Вот почему мне нужно {}обернуть ()и <>, но тогда использование aдля размещения всего в массиве короче, чем [...].
Мартин Эндер
10

Python, 67 байт

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

Создает и извлекает выражение, которое выглядит как

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

и проверяет, является ли результат пустым.

Sp3000 сэкономил 8 байтов, указав, что [],(),{}их можно вставлять без кавычек, потому что они являются объектами Python и что два паренса не нужны.

XNOR
источник
8

Yacc, 119 байт

Не использует регулярные выражения / заменить.

%%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;!

Попробуйте здесь: Тестовый пакет !

Я все еще новичок Пит, любая помощь приветствуется.

объяснение

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

Кстати, поздравляю с другим ответом Pyth (который в настоящее время 20 байтов)

FliiFe
источник
Добро пожаловать в программирование головоломок и Code Golf!
Аднан
@ Adnan Спасибо! Это мой первый гольф!
FliiFe
Хороший первый гольф! С некоторыми перестраивая и прочее, вы можете получить до 25: Vz=:z"<>|\[]|{}|\(\)"k;!z. Особенно примечательно, что вам, по сути, никогда не нужно использовать, lесли вам на самом деле не нужно число, и =автоматически угадывает первую переменную, используемую в выражении. Дайте мне знать, если вы хотите, чтобы я объяснил что-нибудь еще в чате
Pyth
@FryAmTheEggman Спасибо! Я не знал, lбыло ненужно, это приятно знать. Сначала я объявил функцию, потому что моя логика была другой, и забыл ее удалить. Должен ли я включить ваш ответ на мой? (Я новичок>. <)
FliiFe
3
Как правило, если он размещен в комментарии, автор комментария хочет, чтобы вы его использовали. Так что давай! :)
FryAmTheEggman
6

Pyth, 20 байт

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

Попробуйте онлайн: Test Suite

Многократно удаляет вхождений [], (), <>и {}путем расщепления и повторного объединения. Проверяет, является ли полученная строка пустой или нет.

Jakube
источник
4

Javascript ES6, 54 байта

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

Использует рекурсивную реализацию замены. Достаточно просто.

Mama Fun Roll
источник
4

Регекс (PCRE аромат), 41 37 байт

^((<(?1)>|{(?1)}|\[(?1)]|\((?1)\))*)$

Просто стандартное решение с рекурсивным регулярным выражением.

Спасибо jimmy23013 за бритье 4 байта

n̴̖̋h̷͉a̷̭̿h̸̡̅ẗ̵̨d̷̰ĥ̷̳
источник
4

Perl, 34 33 байта

Включает +2 для -lp

Запустить с вводом на STDIN:

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

brackets.pl:

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

Находит первую пару скобок без чего-либо между ними и удаляет ее, пока они есть. Затем проверяет, является ли последняя строка пустой.

Тон Хоспел
источник
Не s/\(\)|\[]|<>|{}//&&redo;$_=!$_сработает? :)
Дада
Было бы здорово, если бы вы также могли дать объяснение.
Прашант Похриял
@ Дада Конечно. Я, должно быть, становлюсь старческим ..
Тон Хоспел
4

Brain-Flak , 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 - мой язык сопоставления двухмерных шаблонов, разработанный для этой задачи ; его также можно использовать для сопоставления одномерных строк. Это мой первый ответ. Я изменил 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.
Zgarb
источник
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.

Подобный подход , как и другие ответы: простой цикл , который продолжается до тех пор , пока мы можем удалить один из [], (), или <>(с несколькими посторонними символами , потому что нам нужно , чтобы избежать регулярных выражений специальные). Мы используем $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
AdmBorkBork
источник
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);}

Использует стек.

mIllIbyte
источник
Мне нравится 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.
Миллибайт
Ах я вижу. Тем не менее, есть еще возможности для улучшения: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. Я удивлен, что средний операнд условного оператора может быть назначением. Я думал, что будет ошибка, что-то вроде «отсутствует: до =».
МиллиБайт
@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);}но это пока не работает для ввода ())), так как «выталкивание» из стека фактически не обнуляет значения в массиве.
Миллибайт
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 минут на моем 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считаются правдивыми / ложными, см. Руководство по правилам игры в гольф .
Лайкони
1
Однако четыре строки с закрывающими скобками могут быть заменены a:x#b:y|a==b=x#yна байты до 113: попробуйте онлайн!
Лайкони
2
109 байт: попробуйте онлайн!
Лайкони
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:])
user5983247
источник
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
orlp
источник
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, если она может получить пустую строку таким образом.

eaglgenes101
источник
1

sed, 39 36 байт (34 для кода, 2 для -r)

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

Попробуйте онлайн!

sed версия того, что кажется стандартным подходом. Требуются расширенные регулярные выражения ( sed -r)

Сохранено 3 байта благодаря шарлатану Cows

луч
источник
Вы можете удалить aэто :aи taспасти байт
Kritixi Lithos
@KritixiLithos Видимо, это была ошибка в GNU sed, которая была удалена в 4.3 . Я бы, вероятно, отбросил бы этих персонажей, если бы эта запись была достаточно близка к лидеру, чтобы у нее был шанс на победу, но, поскольку это не так, я просто оставлю ее в более переносимой форме, чтобы она не перестала работать по мере обновления систем до 4.3.
Рэй
1
Оглядываясь назад на это, я уверен, что вы можете сбросить qс /./и сбросить скобки там же. Попробуйте онлайн! Это из-за того, как cработает
Хэндж
@ Cowsquack Спасибо. Ред.
Рэй
0

05AB1E, 9 байтов

žu2ôõ:g2Q

Вход дан в кавычках.

Попробуйте онлайн!

Объяснение:

žu          # Push "()<>[]{}"
  2ô        # Split into pieces of size 2
    õ       # Push empty string
            # Implicit input
      :     # Infinite replacement
       g2Q  # Is length equal to 2?
            # Implicit print
Оливер Ни
источник
0

Clojure, 153 байта

Дольше, чем даже C и Brainfuck отвечает: o

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

Не использует регулярное выражение, вместо этого использует первый символ, чтобы определить, что представляет собой закрывающий тег, и находит первый индекс, в котором эта скобка сбалансирована (накопленная сумма равна нулю). Затем итеративно проверяет, что то, что в скобках и после скобок, является действительным.

Должен посмотреть, есть ли лучший подход ...

NikoNyrh
источник
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

Р, 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 
lebatsnok
источник