Bong bóng các dấu ngoặc!


27

một vài câu hỏi trên trang web này về việc cân bằng dấu ngoặc, và kiểm tra xem dấu ngoặc được cân bằng. Tôi đề nghị đã đến lúc sử dụng những dấu ngoặc cân bằng này cho một cái gì đó!

Trong toán học và lập trình, dấu ngoặc giống như bong bóng, cô lập mọi thứ bên trong tạo thành mọi thứ bên ngoài để mọi thứ bên trong có thể làm mọi thứ trong hòa bình và bất cứ thứ gì bên ngoài chỉ nhìn thấy một đối tượng. Tuy nhiên, một chuỗi dấu ngoặc là một chiều, trong khi bong bóng thường có ít nhất hai chiều. Điều đó có nghĩa là các bong bóng có thể tự do di chuyển xung quanh nhau miễn là chúng không bao giờ chạm vào nhau hoặc giao thoa giữa bên trong và bên ngoài của bất kỳ bong bóng nào khác.

Thử thách

Đầu vào là một chuỗi các dấu ngoặc phù hợp của một loại, tròn (), vuông [], xoăn {}hoặc góc <>. Tùy thuộc vào loại bạn muốn chương trình của bạn chấp nhận và chương trình chỉ chấp nhận một loại dấu ngoặc đơn được chấp nhận. (Phần thưởng tưởng tượng nếu chương trình của bạn có thể xử lý bất kỳ phần nào trong số chúng, điểm thưởng tưởng tượng lớn nếu nó có thể xử lý tất cả chúng trong cùng một đầu vào.) Đầu vào không thể chứa bất cứ thứ gì giữa các dấu ngoặc, mặc dù khoảng trắng được cho phép.

Đầu ra là tất cả các tổ chức có thể có (theo thứ tự tùy ý và bao gồm cả đầu vào ban đầu) của các dấu ngoặc có cùng cấu hình bong bóng, không có hai chuỗi giống nhau. Điều đó có nghĩa là với đầu vào ()(), đầu ra cũng chỉ ()(), mặc dù về mặt kỹ thuật, hai bong bóng có thể hoán đổi vị trí. Đối với phần thưởng tưởng tượng lớn, {}[]()tất nhiên đầu vào sẽ dẫn đến đầu ra gồm 6 phần tử / chuỗi / dòng khác nhau.

Hai cấu hình của bong bóng là "giống nhau" nếu bạn có thể tạo một cái khác bằng cách di chuyển bong bóng xung quanh, mà không để bất kỳ bong bóng nào đi qua từ bên trong một bong bóng khác ra bên ngoài nó, hoặc từ ngoài vào trong. Nếu bạn ví các dấu ngoặc đơn được lồng vào cây (mỗi cặp được khớp là một nút và mỗi cặp được khớp bên trong là một mã con và mỗi cặp được khớp trong đó lại có một mã con của các nút đó, v.v.) trong đó các mã con của bất kỳ nút nào được đặt hàng , sau đó một cấu hình duy nhất của bong bóng là một cây nơi các nút không được sắp xếp.

Bất kỳ định dạng đầu ra hợp lý nào cũng sẽ làm, như trả về một danh sách các chuỗi hoặc danh sách các danh sách các ký tự đơn hoặc một chuỗi với một loại khoảng trắng, hoặc in ra stdouthoặc stderrvới một số dạng ký tự khoảng trắng có thể nhìn thấy (phổ biến nhất là dòng mới hoặc dấu cách) từng tổ chức lại.

Trailing space cho mỗi lần sắp xếp lại và theo dõi và đặt trước các dòng mới / phần tử danh sách trống trước và sau khi đầu ra thực tế được cho phép. Bạn nên sử dụng cùng loại dấu ngoặc trong đầu ra của bạn khi bạn chấp nhận trong đầu vào của mình. Ngoài dấu ngoặc, dòng mới và khoảng trắng như được chỉ định ở đây và bất kỳ dấu phân cách nào bạn sử dụng, không nên in gì (bao gồm các ký tự vô hình / độ rộng bằng không).

Điểm số là số byte trong mã; số lượng thấp nhất cho mỗi ngôn ngữ chiến thắng. Bạn có thể lưu ý xem bạn có nhận được một phần thưởng tưởng tượng, thường xuyên hay lớn, nhưng nó không ảnh hưởng đến điểm số của bạn. Tiền thưởng thực tế là quá khó để cân bằng ngay.

Ví dụ đầu vào-đầu ra

Ví dụ 1:

Đầu vào:

()(())

Đầu ra:

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

Ví dụ 2:

Đầu vào:

(()())()()

Đầu ra:

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

Ví dụ 3:

Đầu vào:

(()(()))()

Đầu ra:

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

Tại sao chúng ta không thể lấy ((()))ví dụ 1? hay ()()()? Có vẻ như bạn đang thiếu hoán vị cho mỗi đầu vào.
Thuật sĩ lúa mì

@WheatWizard Điều đó sẽ không cho cùng một cấu hình bong bóng: một bong bóng lớn với hai bong bóng trống rỗng bên trong.
Arthur

@WheatWizard theo như tôi hiểu, bạn không thể lấy một bong bóng từ bên trong một bong bóng khác ra bên ngoài, hoặc ngược lại.
Grzegorz Puławski

@WheatWizard Tôi đã thêm một lời giải thích nhỏ.
Arthur

7
Btw, Chào mừng đến với PPCG! Thử thách đầu tiên tốt đẹp!
Ông Xcoder

Câu trả lời:


4

CJam , 18 byte

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

Hãy thử trực tuyến!

-2 cảm ơn Business Cat .

Nhận đầu vào dưới dạng một chuỗi chỉ chứa []. Trả về một danh sách các hoán vị (danh sách trống giống như các chuỗi trống trong CJam, vì vậy thay vì []bạn sẽ nhận được "").


Tại sao đầu ra cho [][]chỉ ""? - Có nên kèm theo đầu vào trong một bộ bổ sung []? Nếu vậy tại sao có thêm một bộ []xung quanh cái gì (có thể?) Là đầu ra cho ví dụ đã nói ở trên? Ngoài ra, câu hỏi nêu rõ "Bạn nên sử dụng cùng loại dấu ngoặc trong đầu ra của mình khi bạn chấp nhận đầu vào. Ngoài dấu ngoặc, dòng mới và khoảng trắng như được chỉ định ở đây và bất kỳ dấu phân cách nào bạn sử dụng, không nên in gì", vì vậy tôi ' m không chắc chắn một kết hợp []""được chấp nhận.
Jonathan Allan

@Jonathan ALLan Có tôi nghĩ bạn cần gửi kèm theo [][]một cặp phụ []. Đối với những người khác tôi không thực sự chắc chắn rằng họ không hợp lệ.
Erik the Outgolfer

Tôi nghĩ bạn có thể làm _{{B}%e!}&thay vì_!!{{B}%e!}*
Business Cat

@BusinessCat Có bị &đoản mạch hay gì không?
Erik the Outgolfer

&chỉ chạy khối nếu giá trị khác là trung thực
Business Cat

4

Haskell , 227 210 208 205 byte

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)

Hãy thử trực tuyến!

Điều này thật khó khăn!

Chơi gôn một chút

Đã lưu hai byte nhờ Laikoni

Lưu hai byte nhờ Bruce Forte

Tôi không chắc chắn điều này hoạt động trong mọi trường hợp. Một số giải thích:

  • a!xthêm Chuỗi xvào danh sách Chuỗi cuối cùng trong a(a là loại [[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])sử dụng điều kiện ngắn hơn để diễn đạt ý tưởng đơn giản: tách một Chuỗi trên root )( s. Vd "(()(()))()"cho ["()(())", ""].

  • Chúng ta cần xử lý từng phần của phần tách, sau đó thu thập và nối tất cả các chuỗi để có đầu ra chính xác:

    1. hxử lý một danh sách các phần: nó áp dụng vcho phần đầu tiên và kết hợp kết quả với quy trình của các phần còn lại.

    2. v tổng hợp các kết quả cho mỗi hoán vị của các bộ phận và loại bỏ các bản sao.

Để thêm chế độ xem rộng hơn: về cơ bản bạn có một cây (không phải là nhị phân) với các nút trống. Để lại là (). Bạn phải tạo ra tất cả các hoán vị của các nhánh cho mỗi nút, nhưng bạn không thể lấy một nhánh từ một nút và đặt nó trên một nút khác. Tôi đã làm một loại tìm kiếm sâu đầu tiên.


Bạn có thể thả dấu ngoặc xung quanh init a.
Laikoni

2

Con trăn 2 353 350 331 byte

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])])]

Nhận chuỗi ()là đầu vào và in kết quả.

Hãy thử nó ở đây!

Tôi tránh sử dụng itertools.permutationsvới sự giúp đỡ từ câu trả lời của Paolo cho câu hỏi này .

Cảm ơn Business Cat vì đã tìm thấy 3 byte và cảm ơn ông Xcoder vì 19 byte đáng kinh ngạc!

Giải trình

  1. Tạo một danh sách các bộ dữ liệu của các chỉ số của mỗi ()cặp trong chuỗi đầu vào.
  2. Thả bất kỳ bộ dữ liệu nào từ danh sách được bao quanh bởi một ()cặp khác .
  3. Cắt chuỗi tại các chỉ số của các bộ dữ liệu còn lại.
  4. Lập danh sách từng hoán vị của danh sách các lát.
  5. Tham gia danh sách với một dòng mới để in.

Tôi thấy một vài byte có thể được cạo. Bạn có một số khoảng trắng có thể được loại bỏ, cụ thể là sau printvà tại các điểm như i+1 if(có thể i+1if). Cũng tại một điểm bạn có y[0:i], bạn có thể bỏ qua 0.
Business Cat

Cảm ơn bạn, @BusinessCat! IDE của tôi phàn nàn về một vài trong số đó, vì vậy tôi vẫn đang học một số thủ thuật đánh gôn.
Giải quyết

342 byte (-8 byte) bằng cách sắp xếp lại một số điều kiện để xóa khoảng trắng.
Ông Xcoder

340 byte (-10 byte) bằng cách sử dụng so sánh từ điển so với kiểm tra đẳng thức.
Ông Xcoder

331 byte (-19 byte) vì thử thách cho phép trả về danh sách Chuỗi. yay, chúng tôi đã đánh bại Mathicala :-)
Ông Xcoder

2

JavaScript (Firefox 30-57), 222 byte

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

Mất []dây. Giải trình:

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

Toán học, 337 byte

Không phải để có được điểm golf-code, nhưng để hiển thị việc sử dụng PermutationsDistributetrong vấn đề này. Có thể có những cách tiếp cận tốt hơn, mặc dù.

( seq: trình tự , alt: lựa chọn thay thế)

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}] &

Lấy đầu vào dưới dạng một chuỗi, sử dụng dấu ngoặc nhọn {}. Xuất ra một chuỗi nhiều dòng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.