Заповнюємо дужки


18

Звичайні дужки ( (), [], <>і {}) гарні і однозначна, проте хто - то думав , що це буде ідея добре використовувати символи НЕ кронштейн в дужках. Ці символи, |причому ", неоднозначні. Наприклад

""""

відповідають

(())

або

()()

Неможливо сказати.

Речі починають ставати цікавими, наприклад, коли ви змішуєте типи неоднозначних дужок, наприклад

"|""||""|"

Може бути будь-яке з наступного

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

Завдання

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

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

IO

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

Оцінка балів

Це тому відповіді будуть набрані в байтах, а менша кількість байтів буде кращою.

Тестові справи

"" -> ["()"]
"|"| -> []
||| -> []
"""" -> ["(())","()()"]
""|| -> ["()[]"]
"|"||"|" -> ["([([])])"]    
"|""||""|" -> ["([(([]))])","([()[]()])","([()][()])"]    

4
чекає відповіді BrainFlak
caird coinheringaahing

Чи можемо ми використовувати рядки замість рядків? Як щодо списків цифр чи цілих чисел?
Згарб

@ Zgarb Звичайно, це добре
Опублікувати Rock Garf Hunter

Відповіді:


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

Сітківка , 59 56 55 байт

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

A`_

Спробуйте в Інтернеті! На жаль, тестування для двох наборів відповідних дужок перевищує гольфічність одного .NET-регулярного виразу, тому він дозволяє економити 15 байт, щоб перевірити вручну. Редагувати: Збережено 3 4 байти завдяки @ H.PWiz. Пояснення:

0`"
<$%">

Знайдіть a "і зробіть дві копії рядка, одну з a <і одну з a >. Робіть це по черзі ", щоб кожен "подвоїв кількість рядків.

}0`'
{$%"}

Точно так же з ', {і }. Потім продовжуйте замінювати, поки всі "s та 's на всіх копіях не будуть замінені.

.+
$&_$&

Складіть дублікат дужок, відокремлених а _.

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

У дублікаті багаторазово видаляйте відповідні дужки до тих пір, поки не залишиться жодна, і в такому разі видаліть відповідну дужку _.

A`_

Видаліть усі рядки, які все ще мають _.

Сітківка , 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.

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]

Спробуйте в Інтернеті!

Використовує лише відповідність шаблону та розуміння.


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")
        }
    }

Правки

  • -4 jrtapsell - Перероблений контрольний предикат
  • -2 jrtapsell - true-> 1>0і == 0->< 1

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 Дякую
Джонатан
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.