Заполните в скобках

18

Обычные скобки ( (), [], <>и {}) хороши и однозначна, однако кто - то думал , что это будет идея хорошо использовать символы не кронштейн в скобках. Эти персонажи, |и ", неоднозначны. Например, делает

""""

соответствовать

(())

или

()()

Невозможно сказать.

Вещи начинают становиться интересными, когда вы смешиваете, например, неоднозначные скобки

"|""||""|"

Может быть любой из следующих

([(([]))]),([()[]()]),([()][()])

задача

Ваша задача - взять строку из неоднозначных символов и вывести все возможные сбалансированные строки, которые мог задумать автор.

Более конкретно, вы выводите все сбалансированные строки, которые можно сделать, заменяя |либо либо, [либо ]и "либо (или ). Вы не должны выводить какую-либо сбалансированную строку дважды.

IO

В качестве входных данных вы должны взять строку, состоящую из |и ". Если вы хотите выбрать два отличных символа, отличных от |и, "в качестве замены, вы можете сделать это. Вы должны вывести контейнер сбалансированных строк. Вы можете заменить []и ()на выходе с любыми другими двумя парами скобок ( (), [], <>или {}) вы хотите. Ваш выходной формат должен быть одинаковым во всех сериях.

счет

Это поэтому ответы будут оцениваться в байтах, причем меньшее количество байтов будет лучше.

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

"" -> ["()"]
"|"| -> []
||| -> []
"""" -> ["(())","()()"]
""|| -> ["()[]"]
"|"||"|" -> ["([([])])"]    
"|""||""|" -> ["([(([]))])","([()[]()])","([()][()])"]    
Мастер пшеницы
источник
4
ждет ответа от BrainFlak
caird coinheringaahing
Можем ли мы использовать целые числа вместо строк? Как насчет списков цифр или целых чисел?
Згарб
@ Zgarb Конечно, все в порядке
Волшебник Пшеницы

Ответы:

7

Python 2 , 135 байт

s=input()
for k in range(2**len(s)):
 try:c=''.join("[]() , ,"[int(c)|k>>i&1::4]for i,c in enumerate(s));eval(c);print c[::2]
 except:0

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

Ожидается ввод, как 2002вместо "||", и заключенный в кавычки.

Перебирает все 2 N возможных назначений «open» и «close» для строки, создавая строки cвроде:

"( [ ( ),],[ ( ),],),( ),"

Если eval-ing эта строка выдает исключение, она не имеет аналогов. Если нет, мы печатаем c[::2], давая:

([()][()])()
Линн
источник
6

Retina , 59 56 55 байт

0`"
<$%">
}0`'
{$%"}
.+
$&_$&
+m`^_|(<>|{})(?=.*_)

A`_

Попробуйте онлайн! К сожалению, тестирование для двух наборов соответствующих скобок превышает пригодность одного регулярного выражения .NET, поэтому экономит 15 байтов для проверки вручную. Редактировать: Сохранено 3 4 байта благодаря @ H.PWiz. Объяснение:

0`"
<$%">

Найдите "и сделайте две копии строки, одну с а <и одну с >. Делайте это по одному ", чтобы каждая "удваивала количество строк.

}0`'
{$%"}

Аналогично с ', {и }. Затем продолжайте замену, пока все "s и 's на всех копиях не будут заменены.

.+
$&_$&

Сделайте дубликат скобок, разделенных знаком _.

+m`^_|(<>|{})(?=.*_)

В дубликате несколько раз удаляйте совпадающие скобки, пока не останется ни одного, и в этом случае удалите _также.

A`_

Удалить все строки, которые все еще имеют _.

Retina , 74 71 70 байт

0`"
<$%">
}0`'
{$%"}
Lm`^(.(?<=(?=\3)(<.*>|{.*}))(?<-3>)|(.))+(?(3)_)$

Попробуйте онлайн! Пояснение: первые два этапа, как указано выше. На третьем этапе непосредственно выводится результат сопоставления двух наборов совпадающих скобок. Это использует балансирующие группы .NET. На каждом этапе сопоставления регулярное выражение пытается сопоставить символ, затем ищет пару совпадающих скобок, а затем проверяет, совпадает ли верхняя часть стека с открытой скобкой. Если это может сделать это, это означает, что скобка уравновешивается, и открытая скобка выталкивается из стека. В противном случае предполагается, что мы находимся в открытой скобке, которую нужно поместить в стек. Если эти предположения не выполняются, то стек не будет пустым в конце и совпадение не удастся.

Альтернативный подход, также 74 71 байт:

Lm`^((?=(<.*>|{.*})(?<=(.))).|\3(?<-3>))+(?(3)_)$

Здесь мы смотрим вперед или <... >или {... }, затем оглядываемся назад, чтобы вставить закрывающую скобку в стек. В противном случае нам нужно сопоставить и вытолкнуть закрывающую скобку, которую мы захватили ранее. В этой версии регулярное выражение может даже не доходить до конца строки, но некоторые строки, такие как <<<>, проскальзывают через сеть, если мы не проверим наличие пустого стека.

Нил
источник
1
Вы можете сэкономить несколько байтов при экранировании, используя разные символы
H.PWiz
@ H.PWiz Ах, должно быть, я упустил этот момент из-за использования альтернативных пар скобок, спасибо!
Нил
Вы также можете изменить |на входе
H.PWiz
2

Шелуха , 19 байт

fo¬ω`ḞoΣx½¨÷₂¨ΠmSe→

Попробуйте онлайн! Использует символы dsна входе, а также соответствующие пары скобок deи stна выходе.

объяснение

Идея состоит в том, чтобы сгенерировать все возможные скобки для ввода и сохранить те, которые сводятся к пустой строке, когда мы неоднократно удаляем соседние скобки. Это ¨÷₂¨сжатая строка, которая расширяется в "dest", которая была выбрана, потому что она имеет короткую сжатую форму и состоит из пар символов со смежными кодовыми точками. Таким образом, программа эквивалентна следующему.

fo¬ω`ḞoΣx½"dest"ΠmSe→  Implicit input, say "ddssdd".
                 m     Map over the string:
                  Se    pair character with
                    →   its successor.
                       Result: ["de","de","st","st","de","de"]
                Π      Cartesian product: ["ddssdd","ddssde",..,"eettee"]
f                      Keep those strings that satisfy this:
                        Consider argument x = "ddsted".
   ω                    Iterate on x until fixed:
         ½"dest"         Split "dest" into two: ["de","st"]
    `Ḟ                   Thread through this list (call the element y):
        x                 Split x on occurrences of y,
      oΣ                  then concatenate.
                          This is done for both "de" and "st" in order.
                        Result is "dd".
 o¬                    Is it empty? No, so "ddsted" is not kept.
                      Result is ["destde","ddstee"], print implicitly on separate lines.
Zgarb
источник
2

Perl, 56 55 53 байта

Включает +1в себя дляn

использует [для []и {для{}

perl -nE 's%.%"#1$&,+\\$&}"^Xm.v6%eg;eval&&y/+//d+say for< $_>' <<< "[{[[{{[[{["

Генерирует все 2 ^ N возможностей, затем использует perl, evalчтобы проверить, является ли строка типа '+ [+ {}]' допустимым кодом, и если это так, удаляет +и печатает результат

Тон Хоспел
источник
1

Чистый , 203 186 179 байт

?['(':l][')':t]= ?l t
?['[':l][']':t]= ?l t
?l[h:t]= ?[h:l]t
?[][]=True
?_ _=False
@['"']=[['('],[')']]
@['|']=[['['],[']']]
@[h:t]=[[p:s]\\[p]<- @[h],s<- @t]
$s=[k\\k<- @s| ?[]k]

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

Использует только сопоставление с образцом и понимание.

Οurous
источник
1

Perl, 56 байт

Включает +в себя дляn

Использует вход [для вывода [или]

Использует вход {для вывода {или}

perl -nE '/^((.)(?{$^R.$2})(?1)*\2(?{$^R.=$2^v6}))*$(?{say$^R})^/' <<< "[{[[{{[[{["

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

Тон Хоспел
источник
0

Котлин , 240 236 234 байта

fold(listOf("")){r,c->r.flatMap{i->when(c){'"'->"()".map{i+it}
else->"[]".map{i+it}}}}.filter{val d=ArrayList<Char>()
it.all{fun f(c:Any)=d.size>1&&d.removeAt(0)==c
when(it){')'->f('(')
']'->f('[')
else->{d.add(0,it);1>0}}}&&d.size<1}

украшенный

    fold(listOf("")) {r,c ->
        r.flatMap {i-> when(c) {
            '"'-> "()".map {i+it}
            else -> "[]".map {i+it}
        }}
    }.filter {
        val d = ArrayList<Char>()
        it.all {
            fun f(c:Any)=d.size>1&&d.removeAt(0)==c
            when(it) {
                ')' -> f('(')
                ']' -> f('[')
                else -> {d.add(0,it);1>0}
            }
        } && d.size<1
    }

Тестовое задание

private fun String.f(): List<String> =
fold(listOf("")){r,c->r.flatMap{i->when(c){'"'->"()".map{i+it}
else->"[]".map{i+it}}}}.filter{val d=ArrayList<Char>()
it.all{fun f(c:Any)=d.size>1&&d.removeAt(0)==c
when(it){')'->f('(')
']'->f('[')
else->{d.add(0,it);1>0}}}&&d.size<1}

data class Test(val input: String, val outputs: List<String>)

val tests = listOf(
    Test("""""""", listOf("()")),
    Test(""""|"|""", listOf()),
    Test("""|||""", listOf()),
    Test("""""""""", listOf("(())","()()")),
    Test("""""||""", listOf("()[]")),
    Test(""""|"||"|"""", listOf("([([])])")),
    Test(""""|""||""|"""", listOf("([(([]))])","([()[]()])","([()][()])"))
)

fun main(args: Array<String>) {
    for ((input, output) in tests) {
        val actual = input.f().sorted()
        val expected = output.sorted()
        if (actual != expected) {
            throw AssertionError("Wrong answer: $input -> $actual | $expected")
        }
    }

Правки

jrtapsell
источник
0

C (gcc) , 315 байтов

j,b;B(char*S){char*s=calloc(strlen(S)+2,b=1)+1;for(j=0;S[j];b*=(S[j]<62||*--s==60)*(S[j++]-41||*--s==40))S[j]==60?*s++=60:0,S[j]<41?*s++=40:0;return*s>0&*--s<1&b;}f(S,n,k)char*S;{if(n<strlen(S))for(k=2;k--;)S[n]==46-k-k?S[n]=40+k*20,f(S,n+1),S[n]=41+k*21,f(S,-~n),S[n]=46-k-k:0;else B(S)&&puts(S);}F(int*S){f(S,0);}

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


C (gcc) , 334 байта (старая версия)

j,b;B(char*S){char*s=calloc(strlen(S)+2,1)+1;for(b=1,j=0;S[j];j++){if(S[j]==60)*s++=60;if(S[j]<41)*s++=40;b*=!(S[j]>61&&*--s!=60)*!(S[j]==41&&*--s!=40);}return*s>0&*--s<1&b;}f(S,n,k)char*S;{if(n>=strlen(S))return B(S)&&puts(S);for(k=0;k<2;k++)S[n]==46-k-k&&(S[n]=40+k*20,f(S,n+1),S[n]=41+k*21,f(S,-~n),S[n]=46-k-k);}F(char*S){f(S,0);}

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


Пояснение (старая версия)

j,b;B(char*S){                   // determine if string is balanced
 char*s=calloc(strlen(S)+2,1)+1; // array to store matching brackets
 for(b=1,j=0;S[j];j++){          // loop through string (character array)
  if(S[j]==60)*s++=60;           // 60 == '<', opening bracket
  if(S[j]<41)*s++=40;            // 40 == '(', opening bracket
  b*=!(S[j]>61&&*--s!=60)*       // 62 == '>', closing bracket
   !(S[j]==41&&*--s!=40);}       // 41 == ')', closing bracket
 return*s>0&*--s<1&b;}           // no unmatched brackets and no brackets left to match
f(S,n,k)char*S;{                 // helper function, recursively guesses brackets
 if(n>=strlen(S))                // string replaced by possible bracket layout
  return B(S)&&puts(S);          // print if balanced, return in all cases
 for(k=0;k<2;k++)                // 46 == '.', guess 40 == '(',
  S[n]==46-k-k&&(S[n]=40+k*20,   //  guess 41 == '(', restore
   f(S,n+1),S[n]=41+k*21,        // 44 == ',', guess 60 == '<',
   f(S,-~n),S[n]=46-k-k);}       //  guess 62 == '>', restore
F(char*S){f(S,0);}               // main function, call helper function

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

Джонатан Фрех
источник
Разве вы не можете использовать массивы переменной длины GCC, чтобы избавиться от calloc?
Тон Хоспел
@TonHospel Я тогда, однако, должен либо преобразовать массив в указатель, либо ввести другую индексную переменную, которую я не знаю, стоит ли она этого, поскольку я использую ее *s++в нескольких местах.
Джонатан Фрех
char S[n],*s=Sвсе еще корочеchars*s=calloc(n,1)
Тон Хоспел
@TonHospel Я действительно не знаю почему, хотя , похоже, не работает .
Джонатан Фрех
@ceilingcat Спасибо.
Джонатан Фрех