Пузирі дужки!


27

На цьому сайті є кілька запитань щодо балансування дужок та перевірки того, чи дужки врівноважені. Я пропоную зараз використовувати ці збалансовані дужки для чогось!

У математиці та програмуванні дужки схожі на бульбашки, ізолюючи все, що знаходиться всередині, все, що знаходиться зовні, так що все, що знаходиться всередині, може робити це в спокої, а все, що знаходиться назовні, бачить лише один предмет. Однак рядок дужок є одновимірною, тоді як бульбашки, як правило, принаймні двовимірні. Це означає, що бульбашки вільно пересуваються один до одного, доки вони ніколи не торкаються один одного або не перетинаються між внутрішньою та зовнішньою стороною будь-яких інших бульбашок.

Виклик

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

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

Дві конфігурації бульбашок є "однаковими", якщо ви можете зробити один в інший, переміщаючи бульбашки навколо, не даючи жодному міхуру перетинатися зсередини іншого міхура назовні або ззовні всередину. Якщо ви порівнюєте вкладені дужки з деревами (кожна відповідна пара - один вузол, і кожна відповідна пара всередині - це підвузл, і кожна відповідна пара всередині є підвузлом цих знову тощо), де упорядковані підвузли будь-якого даного вузла , то єдина конфігурація бульбашок - це дерево, де вузли не упорядковані.

Будь-який розумний формат виводу буде виконуватись, як-от повернення списку рядків або список списку одиночних символів або одна рядок з якимось пробілом, або друк до stdoutабо stderrз якоюсь формою видимого символу пробілу (найчастіше нової лінії чи пробілу) між кожна реорганізація.

Пробіли для кожної реорганізації та відстеження та попередніх елементів рядків / порожніх списків до та після фактичного виходу дозволено. Ви повинні використовувати такі ж дужки у своєму висновку, як і у своєму введенні. Крім дужок, нових рядків та пробілів, як зазначено тут, і незалежно від того, яким розділювачем ви користуєтесь, нічого не слід друкувати (включаючи символи невидимої / нульової ширини).

Оцінка - кількість байтів у коді; найнижча кількість кожного виграшу мови. Ви можете відзначити, отримуєте ви уявний бонус, регулярний чи масовий, але це не впливає на ваш рахунок. Фактичні бонуси занадто важкі, щоб правильно збалансувати.

Приклади введення-виведення

Приклад 1:

Вхід:

()(())

Вихід:

()(())
(())()

Приклад 2:

Вхід:

(()())()()

Вихід:

(()())()()
()(()())()
()()(()())

Приклад 3:

Вхід:

(()(()))()

Вихід:

((())())()
()((())())
(()(()))()
()(()(()))

Чому ми не можемо отримати ((()))приклад 1? або ()()()? Схоже, вам не вистачає перестановок для кожного введення.
Пшеничний майстер

@WheatWizard Це не дало б однакову конфігурацію бульбашок: один великий міхур з двома порожніми бульбашками всередині.
Артур

@WheatWizard, наскільки я розумію, ви не можете взяти міхур зсередини іншого міхура назовні, або навпаки.
Grzegorz Puławski

@WheatWizard Я додав невелике пояснення.
Артур

7
Btw, Ласкаво просимо до PPCG! Приємний перший виклик!
Містер Xcoder

Відповіді:


4

CJam , 18 байт

{~{_{{B}%e!}&}:B~}

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

-2 завдяки Business Cat .

Отримує введення лише у вигляді рядка, що містить []. Повертає перелік перестановок (порожні списки такі ж, як порожні рядки в CJam, тому замість цього []ви отримаєте "").


Чому вихід [][]справедливий ""? - Чи слід входити до додаткового набору []? Якщо так, чому існує додатковий набір []навколо того, що (можливо?) Є результатом для вищезгаданого прикладу? Також у запитанні зазначено: "Ви повинні використовувати той самий тип дужок у своєму висновку, який ви приймаєте у своєму вкладі. Крім дужок, нових рядків та пробілів, як зазначено тут, і який би роздільник ви не використовували, нічого не слід друкувати", тому я " м не впевнений, що суміш є []і ""прийнятна.
Джонатан Аллан

@JonathanAllan Так, я думаю, що вам потрібно вкласти [][]додаткову пару []. Для інших я не дуже впевнений, що вони недійсні.
Ерік Аутгольфер

Я думаю, що ви можете зробити _{{B}%e!}&замість цього_!!{{B}%e!}*
Business Cat

@BusinessCat Чи &коротке замикання чи щось таке?
Erik the Outgolfer

&запускає блок лише в тому випадку, якщо інше значення є правдою
Business Cat

4

Haskell , 227 210 208 205 байт

import Data.List
l=last
a!x=init a++[l a++[x]]
h[]=[""]
h(x:y)=["("++z++")"++t|z<-v x,t<-h y]
g(a,r)x|x=='('=(a+1,l$(r++h[]):[r!x|a>0])|1>0=(a-1,l$r:[r!x|a>1])
v s=nub$h=<<(permutations.snd$foldl g(0,[])s)

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

Цей був жорсткий!

Гольф трохи

Збережено два байти завдяки Лайконі

Збережіть два байти завдяки Брюсу Форте

Я не впевнений, що це працює в кожному випадку. Деякі пояснення:

  • a!xдодайте рядок xдо останнього списку рядків у a(a типу [[String]])

  • snd$foldl(\(a,r)x->if x=='('then(a+1,last$(r++[[]]):[r!x|a>0])else(a-1,last$r:[r!x|a>1])використовує коротший умовний, щоб висловити просту ідею: розділити рядок на root )( s. Напр. "(()(()))()"Дає ["()(())", ""].

  • Нам потрібно обробити кожну частину розколу, потім зібрати та з'єднати всі рядки, щоб отримати правильний вихід:

    1. hобробляє список деталей: він стосується vпершої частини та поєднує результат з процесом решти частин.

    2. v агрегує результати для кожної перестановки деталей та видаляє дублікати.

Щоб додати більш широкий вигляд: у вас в основному є дерево (а не двійкове) з порожніми вузлами. Залиште є (). Ви повинні створити всі перестановки гілок для кожного вузла, але ви можете не взяти гілку з вузла і поставити її на інший вузол. Я зробив своєрідний глибинний перший пошук.


Ви можете опустити круглі дужки навколо init a.
Лайконі

2

Пітон 2, 353 350 331 байт

s=input()
f=lambda i,t=0:i+1if t<0else f(i+1,t-1)if"("<s[i+1]else f(i+1,t+1)
c=[(x,f(x))for x in range(len(s))if")">s[x]]
p=lambda l:[[]]if len(l)<1else[x for y in p(l[1:])for x in[y[:i]+[l[0]]+y[i:]for i in range(len(y)+1)]]
print[''.join(x)for x in p([s[c[x][0]:c[x][1]]for x in range(len(c))if all(c[x][1]>y[1]for y in c[:x])])]

Отримує рядок ()як вхідний і друкує результат.

Спробуйте тут!

Я уникав використовувати itertools.permutationsза допомогою відповіді Паоло на це питання .

Дякую Business Cat за те, що знайшли 3 байти, і дякую містеру Xcoder за неймовірні 19 байт!

Пояснення

  1. Створіть список кортежів індексів кожної ()пари у вхідному рядку.
  2. Викиньте будь-які кортежі зі списку, які оточені іншою ()парою.
  3. Наріжте рядок за показниками інших кортежів.
  4. Складіть список кожної перестановки зі списку фрагментів.
  5. Приєднайтесь до списку новим рядком для друку.

Я бачу кілька байтів, які можна було поголити. У вас є пробіл, який можна видалити, а саме після printта на місцях, як-от i+1 if(може бути i+1if). Також в одному з ваших місць y[0:i]ви можете опустити 0.
Business Cat

Дякую, @BusinessCat! Мій IDE скаржиться на деякі з них, тому я все ще вивчаю деякі хитрощі з кодовим гольфом.
Розв’язання

342 байти (-8 байт) шляхом переупорядкування деяких умовних умов, щоб видалити пробіл.
Містер Xcoder

340 байт (-10 байт) за допомогою лексикографічного порівняння для перевірки рівності.
Містер Xcoder

331 байт (-19 байт), оскільки виклик дозволяє повернути список рядків. так, ми побили Математику :-)
Містер Xcoder

2

JavaScript (Firefox 30-57), 222 байти

s=>(g=a=>a+a?[for(x of g(a[0]))for(y of a.keys())for(z of g(a.slice(1)))(z.splice(y,0,x),z)]:[a])(eval(`[${s.replace(/]\[/g,`],[`)}]`)).map(g=a=>`[`+a.map(g).join``+`]`).sort().filter(s=>t<(t=s),t=``).map(s=>s.slice(1,-1))

Бере []струни. Пояснення:

s=>(                                Inner function to permute an array
 g=a=>a+a?[                         If array is not empty
  for(x of g(a[0]))                 Permute the first element of the array
  for(y of a.keys())                Generate a list of insertion points
  for(z of g(a.slice(1)))           Permute the rest of the array
  (z.splice(y,0,x),z)]:             Make all possible permutations
  [a]                               Otherwise return a list of an empty array
)(eval(`[${                         Convert the string to a nested array
   s.replace(/]\[/g,`],[`)}]`)      ... inserting commas where necessary
).map(                              Process the results
 g=a=>`[`+a.map(g).join``+`]`       Recursively convert back to string
).sort().filter(s=>t<(t=s),t=``     Check for duplicates
).map(s=>s.slice(1,-1))             Remove outer `[]`s

0

Mathematica, 337 байт

Не отримувати очки з кодом для гольфу, а показати використання Permutationsта Distributeв цій проблемі. Однак можуть бути і кращі підходи.

( seq: послідовність,: altальтернативи)

SetAttributes[alt, {Flat, OneIdentity}]
StringTake[
  StringReplace[ToString[
    ToExpression["{" <> StringReplace[#, "}{" -> "},{"] <> "}"]
        /. List -> Permutations@*seq
       /. List -> alt
      /. seq -> (Distribute[seq@##, alt] &)
     /. {seq -> List, alt -> Alternatives}],
   {", " -> "", "} | {" -> "\n"}],
  {2, -2}] &

Візьміть дані як рядок, використовуючи фігурні дужки {та }. Виведіть багаторядковий рядок.

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