Сбалансированная строка - это строка скобок, ()
так что каждая скобка может быть сопоставлена с другой. Более строго они - последовательности, натянутые этой грамматикой:
S → (S)S | ε
Мы можем перевернуть строку "наизнанку":
Переключение всех вхождений
(
и)
друг с другомПеремещение символов от начала строки до конца, пока строка снова не будет сбалансирована.
Давайте сделаем пример.
Начнем со сбалансированной строки:
(()(())())
Затем мы переключаем парены, чтобы сделать
))())(()((
Затем переместите символы от начала строки до конца строки, пока строка не будет сбалансирована.
))())(()((
)())(()(()
())(()(())
))(()(())(
)(()(())()
(()(())())
Вот наш результат!
Обратите внимание, что некоторые строки можно вывернуть наизнанку несколькими способами, например, строку
(()())
Когда вывернута наизнанку может быть:
()(())
или
(())()
Однако каждая строка имеет хотя бы одно решение .
задача
Напишите программу, которая будет принимать сбалансированную строку в качестве входных данных и выводить эту строку наизнанку. В случаях, когда может быть несколько действительных выходов, вам нужно вывести только один из них. Вы можете использовать другой тип распорки ( <>
, []
или {}
) , если вы так хотите.
Это соревнование по коду-гольфу, поэтому вы должны стремиться минимизировать размер исходного кода, измеряемый байтами.
Тестовые случаи
(()()) -> ()(()), (())()
(()(())()) -> (()(())())
((())())() -> (()(()()))
источник
Ответы:
Haskell ,
12412011911711311010910610510410198 байт4 байта сэкономлено благодаря bartavelle!
3 байта сохранены благодаря Zgarb
1 байт сохранен благодаря Питеру Тейлору
Вот решение, которое я разработал в Haskell. Его
хорошо прямо сейчасдовольно хорошо благодаря некоторой помощи я получил, но я ищу , чтобы сделать это короче, поэтому обратная связь / предложения приветствуются.Попробуйте онлайн!
объяснение
Эта программа определяет 4 функции, первая
(!)
определяет, сбалансирована ли строка. Его определяют следующим образом:Эта проверка предполагает, что вход имеет одинаковое количество открытых и закрытых парен, благодаря предложению Питера Тейлора.
Следующий
g
будет вращать строку один раз.Тогда у нас есть,
d
который просто берет парен и отражает егоНаконец, у нас есть функция, которая нас интересует. Здесь мы используем представление без точек,
until(!0)g
составленное сmap d
, которое отображаетсяd
на вход и применяется,g
пока результат не будет сбалансирован. Это точный процесс, описанный в вопросе.источник
g x@(a:b)|x!0=x|1>0=g$b++[a]
и снять с них символыd '('=')'
.d
вызывает ошибку компилятора, поверьте мне, я пробовал. Но первое предложение приветствуется. Благодарность!!
потому что вам не нужно обрабатывать случаи, когда строка содержит неодинаковое количество открытых и закрытых скобок, поэтому вы можете поменять местами первые два случая и получить_!1=1<0
[]!_=0<1
until
для сокращенияg
: TiOd
карту'('
на(-1)
и что - нибудь еще1
, а затем две длинные случаи!
могут быть объединены(i:a)!x=a!(x+i)
. Затем структура верхнего уровня нуждается в доработке, чтобы перейтиmap d
вuntil
состояние, и мне нужно бежать, чтобы у меня сейчас не было времени выяснить, какие комбинаторы требуются, чтобы склеить все это вместе.SOGL V0.12 ,
1211 байтовПопробуй здесь!
Объяснение:
Примечание:
l{
можно заменить на ( для 10 байтов, но, к сожалению, это не реализовано.источник
CJam (20 символов)
Онлайн демо
или для того же количества символов
Онлайн демо
рассечение
Две версии имеют общий колонтитул
Тогда бит в середине, очевидно, вычисляет, как далеко нужно повернуть. Оба они используют оценку и полагаются на
(
то, чтобы быть оператором декремента CJam и)
оператором приращения.против
источник
JavaScript (ES6),
111105 байт(Сохранено 2 байта благодаря @CraigAyre, 2 байта благодаря @PeterTaylor, 2 байта благодаря @Shaggy.)
Ungolfed:
Тестовые случаи:
Показать фрагмент кода
источник
Сетчатка ,
4638 байтПопробуйте онлайн! Ссылка включает в себя тестовые случаи. Редактировать: 8 байтов с помощью @MartinEnder. Первый этап просто переносит скобки, а второй этап ищет самый длинный суффикс, который является действительным сбалансированным префиксом, что, по-видимому, является достаточным условием для полной сбалансированности вращения. Балансировка определяется с помощью балансировочных групп. Конструкция
((\()|(?<-4>\)))+
соответствует любому количеству(
s плюс любое количество)
s, если мы уже (<-4>
) видели столько же(
s. Так как мы ищем только действительный префикс, нам не нужно совпадать с остальными)
s.источник
((\()|(?<-2>\)))
. Но ваша попытка просто вдохновил меня , чтобы найти совершенно новый подход , который позволяет экономить еще два:(?<-1>(\()*\))+
. Это, безусловно, пригодится в будущем, так что спасибо. :)(?<-1>(\()*\))+
работает, так как кажется, что он хочет выскочить из1
стека, прежде чем что-то действительно совпадет ...\(*
хотя.PHP,
110108 байтЗапустите как трубу с
-nR
или проверьте это онлайн .сломать
источник
Python 3 ,
112103101 байт-2 байта благодаря @ Mr.Xcoder
Попробуйте онлайн!
источник
Октава, 62 байта
Попробуйте онлайн!
Функция, которая принимает строку в качестве входных данных и печатает все результаты.
Объяснение:
источник
Mathematica, 78 байт
источник
JavaScript (ES6), 97 байт
Работает, рекурсивно вращая входную строку, пока ее транспонирование не будет сбалансировано, затем транспонируя ее.
источник
APL (Dyalog Unicode) ,
3530 байтИгра в гольф по-новому благодаря @ Adám
Попробуйте онлайн!
Игра в гольф продолжается.
объяснение
источник
Python 2 , 99 байт
Попробуйте онлайн!
В функциональной форме для простых тестовых случаев:
Python 2 , 108 байт
Попробуйте онлайн!
При этом используется немного другой подход - вместо рекурсивного поворота строки, если мы думаем о паренах как о приращении и уменьшении некоторого счетчика баланса, тогда у сбалансированной строки никогда не должно быть общей суммы приращений - приращений меньше 0.
Итак, мы берем
инвертировать парены:
и преобразовать его в список сумм приращений / уменьшений:
-3 - минимум по индексу 4 (на основе нуля); поэтому мы хотим сдвинуться на этот индекс + 1. Это гарантирует, что совокупный прирост / уменьшение никогда не будет меньше 0; и составит до 0.
источник
r=0,
вместоr=[0]
?r+=[r[-1]+2*b-1]
сr+=r[-1]+2*b-1,
аClojure, 118 байт
Возвращает последовательность символов, поэтому я бы назвал это так:
Сначала переворачивайте скобки, затем повторяйте циклы до тех пор, пока кумулятивная сумма количества скобок станет отрицательной в некоторой точке последовательности.
источник
брейкфук , 82 байта
Попробуйте онлайн!
объяснение
С каждым прочитанным символом счетчик изменяется следующим образом:
)
счетчик увеличивается на 1.(
счетчик уменьшается на 1, если только счетчик не был равен 0, в этом случае счетчик не изменяется.Каждый префикс является действительным суффиксом сбалансированной строки (после инверсии) тогда и только тогда, когда этот счетчик равен 0. Этот код использует самый длинный такой префикс для формирования выходных данных.
источник