Мы называем группу паренов открытым пареном (
, его близким паренем )
и всем, что внутри.
Группа или строка parens называется сбалансированной в скобках, если она не содержит ничего или содержит только две группы parens, сбалансированных в скобках.
Например:
The string "(()())()" is parenthesly balanced
( )() Because it contains exactly 2 parenthesly balanced parens groups
()() The left one is parenthesly balanced because it contains 2 parenthesly balanced parens groups (balanced because they are empty). The right one is parenthesly balanced because it contains nothing.
Точно так же:
The string "(()(()))()" is not parenthesly balanced
( )() Because it contains a parens group that is not parenthesly balanced: the left one
()( ) The left one is not balanced because it contains a parens group that is not balanced: the right one
() The right one is not balanced because it only contains one balanced group.
Таким образом, строка со скобками в скобках или группа скобок должны:
- Вообще ничего не содержать
- Или содержат только и ровно 2 группы сбалансированных скобок. Он не должен содержать ничего другого.
Задача:
Ваша задача - написать функцию или программу, которая проверяет, является ли данная строка сбалансированной в скобках или нет.
Входные данные:
На входе будет строка или список символов или что-то подобное. Вы можете предположить, что строка будет состоять только из символов '('
и ')'
. Вы также можете предположить, что у каждого открытого парена (
будет свой близкий парен )
, поэтому не беспокойтесь о строках типа "((("
или ")("
или "(())("
...
Примечание: Как упомянуто @DigitalTrauma в своем замечании сильфона, это нормально subtitute с ()
комбо другими символами (например <>
, []
...), если это вызывает дополнительную работу , как избежать в некоторых языках
Выход:
Все, что указывает на то, сбалансирована ли строка в скобках или нет (true или false, 1 или 0, ...). Пожалуйста, укажите в своем ответе, что ваша функция / программа должна приносить.
Примеры:
"" => True
"()()" => True
"()(()())" => True
"(()(()(()())))(()())" => True
"(((((((()())())())())())())())()" => True
"()" => False
"()()()" => False
"(())()" => False
"()(()(())())" => False
"(()())(((((()())()))())())" => False
"()(()()()())" => False
"()(()(()())()())" => False
Последние два примера действительно имели значение!
Удачи!
источник
"(()())()"
будет представлен как[0, 0, 1, 0, 1, 1, 0, 1]
. Это избавило бы от необходимости преобразовывать ввод в символьный код и затем вычитать.Ответы:
Japt v2, 20 байт
Проверьте это онлайн!
Сначала все неправильно поняли задачу, и хотя каждая пара скобок должна была содержать четное число подпар, тогда как на самом деле в запросе запрашивается 0 или 2 подпары. Итак, вот мой пересмотренный ответ, используя ту же технику, что и раньше.
Мы все еще можем решить проблему с рекурсивной заменой. Дело в том, что вместо того, чтобы просто удалить все вхождения
()()
, нам нужно убедиться, что в этой же оболочке()()
нет()()()()
ничего, кроме (другими словами, нет или что- то в этом роде ). Мы можем сделать это путем рекурсивной замены(()())
на()
.Новая проблема состоит в том, что у самого ввода нет одной пары внешних скобок (поскольку это сделало бы его строкой, не сбалансированной в скобках), что вынуждает нас обернуть его в дополнительную пару, чтобы полностью уменьшить его. Наконец, конечный результат для сбалансированных строк теперь
()
вместо пустой строки, поэтому мы проверяем равенство, а не просто принимаем логическое НЕ вывода.источник
сед 4.2.2, 30
Попробуйте онлайн .
Это возвращает код завершения оболочки 1 для True и 0 для False.
источник
Perl 5- lp,
2422 байтаПопробуйте онлайн! Ссылка включает в себя тестовые случаи. Редактировать: 2 байта сохранены благодаря @JoKing. Пояснение: просто рекурсивное регулярное выражение. Внешняя группа захвата представляет сбалансированную строку,
<
за которой следует необязательная сбалансированная строка, за которой следует>
дважды. Обратите внимание, что большинство других ответов могут использовать()
s, но это стоит дополнительных двух байтов:Попробуйте онлайн! Ссылка включает в себя тестовые случаи.
источник
<>
()
s, поэтому я не думал, что это было справедливое сравнение, однако я вижу, что в ответе @ ngn APL также используются<>
s, поэтому я обновил этот.6502 машинного кода , 48 байтов
Ожидает указатель на строку в
$fb
/,$fc
которая должна содержать только(
и)
. Сбрасывает флаг C (Carry), если строка «сбалансирована по парантезе», устанавливает ее иначе (что является типичной идиомой для 6502, установите перенос «при ошибке»). Ничего толкового при неправильном вводе не делает.Хотя алгоритм рекурсивный, он не вызывает сам себя (что потребует большего количества байтов и делает позицию кода зависимым), но вместо этого поддерживает глубину рекурсии и использует «простое» ветвление.
Прокомментировал разборку
Пример C64 ассемблерной программы с использованием подпрограммы:
Онлайн демо
Код в синтаксисе ca65 :
источник
V ,
21, 20 байтовПопробуйте онлайн! или проверьте все контрольные примеры!
HexDump:
источник
Брахилог , 28 байт
Попробуйте онлайн!
объяснение
источник
C (gcc) , 113 байтов
Попробуйте онлайн!
объяснение
Попробуйте онлайн!
источник
MATL ,
2625 байтПопробуйте онлайн!
Благодаря ответу @ETHProductions за идею "replace (() ()) with ()" и комментарию вопроса @JungHwan Min за идею видеть скобки в виде двоичных цифр.
Выходные данные - это пустой массив для truey, положительное число для falsey, которое, как мне кажется, допускается комментарием OP: «Могут быть категории. То есть истинные значения, указывающие на истинность, и ложные значения, указывающие на обратное» Если это не так, мы можем добавить
n
в конце +1 байт, чтобы иметь 0 в качестве истинного вывода и 1 в качестве ложного вывода.С комментариями:
источник
C # (.NET Core) ,
7871 байтПопробуйте онлайн!
источник
Haskell ,
8259 байтПопробуйте онлайн!
Я предполагаю, что это может быть игра в гольф намного дальше, так как я впервые играю в гольф на Haskell, поэтому любые трюки или комментарии приветствуются.
РЕДАКТИРОВАТЬ - Спасибо @nimi за сохранение 23 байта (более 28% от первоначального представления :)
источник
()
вокругy+1
. Как безымянные функции разрешены, вы можете опускатьf=
,r[0]
является надлежащее функционирование. Поместите базовый регистрr b[]
в конец и переключитесь на инфиксную функцию (скажем#
), затем вы можете использоватьb#_=
. Вы также можете немного изменить свой алгоритм, создав список для пошаговой проверки0
s и2
s, вместо того, чтобы переносить вызовыr
в аккумулятореr(x:y:z) ... = x : r (...) a
с базовым регистромr b [] = b
. Сделайте проверку после первого звонкаr[0]
. Всего 73 байта.foldl
(59 байт): попробуйте онлайн! ,JavaScript (ES6), 63 байта
Принимает ввод как массив символов. Возвращает false для сбалансированных по скобкам, true для не сбалансированных по скобкам.
Попробуйте онлайн!
комментарии
Рекурсивный, 54 байта
Использование рекурсивных замен (как в ответе Japt от ETHproductions ) значительно короче.
Принимает ввод в виде строки. Возвращает 1 для сбалансированных по скобкам, 0 для не сбалансированных по скобкам.
Попробуйте онлайн!
Рекурсивный, 46 байт
Этот бросает ошибку рекурсии для не сбалансированного в скобках:
Попробуйте онлайн!
источник
x[k]
изначально не определено иx[k]++
дастNaN
, а-~undefined
дает1
.a[k]
изначально содержит символ. Но та же логика применима к строкам: применение++
оператора к ним приводит к получениюNaN
, но побитовые операторы (такие как~
) заставляют их принудительно вызывать0
заранее.Perl 6 ,
43 4137 байтПроверь это
Проверь это
Проверь это
Expanded:
источник
R , 71 байт
Попробуйте онлайн!
Другое, более продолжительное решение, но интересное для другого подхода.
R 85 байт
Попробуйте онлайн!
Пояснение:
Возьмите входную строку и замените:
затем оценивает полученное выражение. Если он равен нулю, он сбалансирован, иначе нет. Использование
sum
необходимо только для обработки пустого строкового регистра, потому что его оценка возвращаетсяNULL
.например
источник
f=function(s,r=sub('(()())','()',s,f=T))'if'(r==s,s==''|s=='()()',f(r))
Wolfram Language (Mathematica) , 65 байт
Попробуйте онлайн!
источник
05AB1E ,
181613 байтПорт ответа @ETHproductions на Japt для исправления тестового примера
()(()()(()())(()()))
.-2 байта благодаря @Adnan .
Основываясь на этом комментарии OP, я теперь использую
()
как истинное значение, а все остальное как ложь. Если оба значения должны быть непротиворечивыми, а не только одно, это будет старый 16-байтовый ответ вместо (…(ÿ)…(()∞„()©:®Q
), возвращающий0
байтовый для истинных и1
ложных тестовых случаев.Попробуйте онлайн илипроверьте все контрольные примеры .
объяснение
(Старый 18-байтовый ответ, который не удался для контрольного примера
()(()()(()())(()()))
..):Попробуйте онлайн или проверьте все контрольные примеры .
источник
„()∞õ:g_
.(()()()())
сработало для тестовых случаев, которые должны возвращать false. Каждая группа скобок должна содержать ровно 0 или 2 внутренних группы.'(®')J
на…(ÿ)
.ÿ
существует, но никогда не использовал его раньше, поэтому совершенно забыл об этом.APL (Dyalog Classic) , 27 байтов
Попробуйте онлайн!
источник
Пролог , 46 байт
Попробуйте онлайн! или проверьте все контрольные примеры!
Использует списки
l
и вr
качестве входных данных, например"()()"
, проверяется какf([l,r,l,r]).
.Первые три строки - это грамматика допустимых строк в синтаксисе грамматики « Определенное предложение» Пролога .
a(A,B).
возвращаетtrue
когдаA
список, следующий за грамматикой иB
пустой. Таким образом, основная функцияf
берет некоторыеX
и проверяет,a(X,[])
выполняется ли .источник
Python 2 ,
7371 байтПопробуйте онлайн!
источник
брейкфук, 50 байт
отформатирован:
Ожидается строка с завершающим символом новой строки
(
и)
без нее, а также выводится значение\x01
true и\x00
false. (Для разборчивости вы можете, например, добавить 48+
с до финала,.
чтобы сделать его печатным1
и0
вместо этого.)Попробуйте онлайн
Это поддерживает стек с количеством групп на каждой глубине, выделяя символы по четности и проверяя, находится ли число групп в {0, 2} после каждой закрывающей скобки; если условие не выполняется, потребляет оставшуюся часть ввода и устанавливает флаг; затем снова проверяет условие в конце программы.
Если нам разрешено завершать входной поток нечетным символом, мы можем пропустить последнюю проверку,
<[--[>->]]
чтобы сохранить 10 байтов. (Если бы\n
не было даже неудобства, я мог бы предложить этот вариант в качестве основного ответа.)(Мы могли бы также сохранить несколько байтов, изменив формат вывода
\x00
на true и не\x00
на false, что, как представляется, допускается (возможно, случайно) в заявлении о проблеме, как написано, но в любом случае это не будет очень интересно, и я предпочитаю не делать этого изменения.)источник
Python2,
9594 байтаПопробуйте онлайн!
Функция f () преобразует строку во вложенный кортеж, который передается в g ().
g () рекурсивно перемещается по кортежу и возвращает False, если какой-либо элемент не имеет точно 0 или 2 дочерних элементов.
Сохранение одного байта с использованием форматирования строки.
источник
Stax ,
1311 байтЗапустите и отладьте его
Я сохранил два байта, когда понял, что входные данные могут быть неявно оценены как литералы массива. Удаляя двойные кавычки, ввод упрощается.
Общая идея состоит в том, чтобы оценить входные данные как литерал массива и рекурсивно отобразить элементы, чтобы проверить баланс между ними. Если окончательное утверждение когда-либо не удастся, тогда будет пустой всплеск. В stax всплывание с пустыми стеками немедленно завершает программу.
Распакованный, размазанный и прокомментированный, это выглядит так.
Запустите этот
источник
Java 10,
99969583 байтаПорт моего ответа 05AB1E (так же возвращается
()
как правдивый и все остальное как фальси).Попробуйте онлайн.
Объяснение:
return s;
может быть,return"()".equals(s);
если требуется фактический логический результат.источник
!s.contains("()()(")