Кронштейн балансировочный

20

Вам будет предоставлена ​​(возможно, пустая) строка, содержащая скобки ( [{()}]) и любые другие символы ( A- Z, a- z, 0- 9, знаки пунктуации). Вам необходимо проверить, соответствует ли он следующим правилам:

  • Не заключенные в скобки символы игнорируются.
  • Каждая открытая скобка [{(имеет закрывающую скобку )}]. Так [](что не допускается.
  • Скобки правильно вложены. [(])не разрешено.
  • Вьющиеся скобки не могут содержать квадратные скобки внутри них. Простые скобки не могут содержать ни фигурных, ни квадратных скобок внутри них. Так [({})], [{[]}]и ({})не допускаются. Скобки могут быть вложены в одинаковые скобки, поэтому [[{((()))}{{(())}}]()]{()}это разрешено.

Выход - единственное значение true / falsey согласно вашему выбору.

Самый короткий код выигрывает.


Контрольные примеры

b[[a{(/)}(())+={{}-}],] -> Действительный

([h][e][l][l][o]) -> Неверный

[///[{(\/(arg()))}1{{((-)-2)}}]()]{()} -> Действительный

hi -> Действительный

ghosts_in_the_code
источник
2
Возможный дубликат несбалансированных скобок Fix
FUZxxl
9
@FUZxxl Это выглядит намного сложнее. Я чувствую, что где-то есть еще один обман.
Мартин Эндер
@ MartinBüttner Да, это возможно. Я добавил несколько тестов. И вы нашли дубликат, который искали?
ghosts_in_the_code
1
@ MartinBüttner: этот вызов может быть тем, о чем вы подумали.
Ильмари Каронен
1
Я думаю, что мы должны закрыть другой вопрос как дубликат этого; это лучше, потому что у него меньше бонусов.
lirtosiast

Ответы:

5

Сетчатка , 84 байта

^([^][}{)(]|()\(|(?<-2>)\)|(?!\2)((){|(?<-4>)}|(?!\4)(()\[|(?<-6>)])))*$(?!\2|\4|\6)

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

Это довольно прямолинейное (но удачное) расширение базового регулярного выражения для проверки скобок .NET .

Хотя это вполне возможно при балансировке групп, рекурсия Perl определенно имеет здесь преимущество . Тем не менее, любой из этих подходов побежден, если отбросить элегантность одного совпадения с регулярным выражением в пользу постепенного сокращения входных данных путем повторных замен, как это делает ответ Digital Trauma sed . Это может быть реализовано в 34 байта в Retina, но я не решаюсь опубликовать код сам, так как я не придумал идею.

Мартин Эндер
источник
5

Сетчатка, 34

Во-первых, кредит, где кредит должен:

Я независимо (позже) придумал тот же подход в sed , поэтому я надеюсь, что я не наступлю ни на какие пальцы ( большие или нет), опубликовав это:

[^][(){}]

+`\(\)

+`{}

+`\[]

^$

Так что теперь с sudo apt-get install mono-completeи у git clone https://github.com/mbuettner/retina.gitменя есть рабочая сетчатка на моей Ubuntu VM. Вот результат теста:

$ while read; do echo "Input: \"$REPLY\", Ouput: $( mono Retina.exe -s brbal.ret <<< "$REPLY" )" ; done < ../brbal.txt 
Input: "[[{((()))}{{(())}}]()]{()}", Ouput: 1
Input: "b[[a{(/)}(())+={{}-}],]", Ouput: 1
Input: "[///[{(/(arg()))}1{{((-)-2)}}]()]{()}", Ouput: 1
Input: "hi", Ouput: 1
Input: "", Ouput: 1
Input: "", Ouput: 1
Input: "([h][e][l][l][o])", Ouput: 0
Input: "[](", Ouput: 0
Input: "[(])", Ouput: 0
Input: "[({})]", Ouput: 0
Input: "[{[]}]", Ouput: 0
Input: "({})", Ouput: 0
$ 
Цифровая травма
источник
@ThomasKwa Смотрите результаты теста. Я считаю, что код правильный и все тесты пройдены. Была ли какая-то конкретная проблема, которую вы видите в коде, или конкретный тестовый сценарий, по вашему мнению, потерпит неудачу?
Цифровая травма
@ThomasKwa Я не портировал их код, потому что понятия не имею, что делает какая-то часть ESMIN. Я просто написал этот код, основываясь на том, как он выглядит , так что я не думаю, что есть какая-то причина, по которой у него должна быть та же ошибка.
Мартин Эндер
Вау, @ MartinBüttner, ты правильно понял! Да, я думал, что рекурсивная замена соответствующих скобок наизнанку была наиболее логичной. Быстрая настройка в соответствии со спецификациями кода заставила его работать.
Mama Fun Roll
3

Сед, 53

s/[^][(){}]//g
:;s/()//;t
:b;s/{}//;tb
:c;s/\[\]//;tc

Здесь я утверждаю, что, поскольку на sedсамом деле нет понятия истина / ложь, я определяю пустую строку как истину, а все остальные строки - как ложь.

Если это не приемлемо, мы можем добавить пару строк, таким образом:

Сед, 66

s/[^][(){}]//g
:;s/()//;t
:b;s/{}//;tb
:c;s/\[\]//;tc
/./c0
/^$/c1

Это выводит 0 для false и 1 для true.

Цифровая травма
источник
См. Мой комментарий к ответу molarmanful для версии Retina того же самого решения (в 34 байтах; печать 0или 1). Я не могу сказать, кто должен опубликовать это, но это должен быть один из вас двоих.
Мартин Эндер
3

CJam, 27 26 байтов

"(){}[]"q1$f&_,@2/e*{/s}/!

Это печатает 1 (правда) или 0 (ложь). Попробуйте онлайн! или проверьте все контрольные примеры.

Как это устроено

"(){}[]"                    Push that string.
        q                   Read all input and push it on the stack.
         1$                 Copy the bracket string.
           f&               Intersect each input character with the bracket string.
                            This pushes an array of singleton and empty strings.
             _,             Get the length of the array (L), i.e., the number of
                            characters in the original input.
               @            Rotate the bracket string on top of the stack.
                2/          Split it into ["()" "{}" "[]"].
                  e*        Repeat each character pair L times.
                    {  }/   For each character pair.
                     /      Split the string on the stack at occurrences of that
                            character pair. This dosn't work properly the first
                            time, since there's a string array on the stack.
                      s     Flatten the resulting array of strings.
                         !  Apply logical NOT.
Деннис
источник
3

𝔼𝕊𝕄𝕚𝕟, 43 символа / 62 байта

!Մ(Մ(Մ(ïċ/⁅⬮[\]{}]⌿),`⬮`,⬯),`{}`,⬯),`[]`,⬯)

Try it here (Firefox only).

Нет.


Однако, если я использую недавно реализованные функции, я могу получить до 28 символов / 47 байт:

!ïċ/⁅⬮[\]{}]⌿)ė`⬮”ė`{}”ė`[]”
Mama Fun Roll
источник
Оооо, вы удаляете соответствующие скобки изнутри? Это будет всего 34 байта в сетчатке: pastebin.com/bU77LzbR
Мартин Эндер,
2

Japt , 42 37 байт

Сохранил 5 байтов с функцией, которую я не знал, что мой родной язык был ... Спасибо за добавление, @Downgoat!

Japt действительно нуждается в лучшей поддержке RegExp ...

!Uo"()[\\]\{}" e"\\(\\)" e"\{}" e"\\[]

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

Как это устроено

               // Implicit: U = input string
Uo"()[\\]\{}"  // Remove all non-bracket.
e"\\(\\)"      // Recursively remove all pairs of simple brackets.
e"\{}"         // Recursively remove all pairs of curly brackets.
e"\\[]         // Recursively remove all pairs of square brackets.
!              // Return the Boolean NOT of the result.
               // (true for empty string, false for anything else)
               // Implicit: output last expression
ETHproductions
источник
2

C99, 226 208 207 байт

Я впервые пытаюсь что-то сыграть в гольф

#define S s[i]
t(s,i)char*s;{int a[]={['[']=0,['{']=0,['(']=0};for(i=0;S*!(S=='{'&a['(']|S=='['&(a['(']|a['{'])|S==']'&(a['(']|a['{'])|S=='}'&a['(']);i++)a[S]++,a[S-S/90-1]--;return !(a['[']+a['{']+a['(']);}

Удобочитаемый:

int t(char* s){
    int a[265]={['[']=0,['{']=0,['(']=0};
    for(int i=0;s[i]&&!((s[i]=='{'&a['(']>0)|(s[i]=='['&(a['(']>0|a['{']>0))|(s[i]==']'&(a['(']>0|a['{']>0))|(s[i]=='}'&a['(']>0));i++){
        a[s[i]]++;
        a[s[i]-(s[i]/90+1)]--;
    }
    return !(a['[']+a['{']+a['(']);
}

Существует переполнение буфера, но, похоже, это ни на что не влияет - я думаю, это связано с выравниванием.

dj0wns
источник
1
Вы можете опустить место вchar* s
Cyoce
Не знал, что - спасибо
dj0wns
1

Perl, 50 + 1 = 51 байт

$_=/^((([^][)(}{]|\((?3)*\))|{(?2)*})|\[(?1)*])*$/

Требуется -pфлаг и печать 1правдивых и ничего для ложных результатов. Я считаю -pодним, потому что это может быть объединено с -e:

> perl -pe '$_=/^((([^][)(}{]|\((?3)*\))|{(?2)*})|\[(?1)*])*$/'

Код в основном представляет собой простое совпадение регулярных выражений с вводом с использованием изящной рекурсивной функции регулярных выражений Perl.

Спасибо Деннису за помощь в тестировании этого и игра в гольф Perl.

Мартин Эндер
источник
1

Python 3: 120 байт

Опираясь на ответ @ Adnan , вы оказались короче, чтобы использовать:

import re
x=re.sub('[^[\](){}]','',input())  
for i in('()','{}','[]'):  
 while x.find(i)>=0:x=x.replace(i,'')  
print(x=='')
karhell
источник
1

Python 3, 196 170 160 154 байта

Неловко долго, спасибо Mego за сохранение 6 байтов:

d=y=""
for C in input():
 for a in "[](){}":y+=C*(C==a)
 y=y.replace("()",d)
x=y
for r in y:x=x.replace("{}",d)
for s in y:x=x.replace("[]",d)
print(x==d)
Аднан
источник