Tạo tất cả các chuỗi có độ dài n


16

Chuỗi *()[]niềng răng được định nghĩa là một chuỗi bao gồm các ký tự trong đó dấu ngoặc nhọn khớp chính xác:

[brace-string] ::= [unit] || [unit] [brace-string]
[unit]         ::= "" || "*" || "(" [brace-string] ")" || "[" [brace-string] "]"

Đây là một chuỗi cú đúp hợp lệ:

((())***[]**)****[(())*]*

Nhưng đây không phải là:

)(
**(**[*](**)
**([*)]**

Nhiệm vụ của bạn là viết một chương trình (hoặc hàm), với một số nguyên dương n, lấy một số làm đầu vào và đầu ra (hoặc trả về) tất cả các chuỗi có độ dài hợp lệ n.

Thông số kỹ thuật

  • Bạn có thể xuất các chuỗi theo thứ tự bất kỳ.
  • Bạn có thể xuất ra dưới dạng một danh sách hoặc một chuỗi được phân tách bằng một ký tự khác.
  • Chương trình của bạn phải xử lý 0 chính xác. Có 1 chuỗi có thể có độ dài 0, đó là chuỗi rỗng "".
  • Đây là , vì vậy câu trả lời hợp lệ ngắn nhất - được đo bằng byte - thắng.

Các trường hợp thử nghiệm

0. 
1. *
2. ** () []
3. *** ()* []* (*) [*] *() *[]
4. **** ()** []** (*)* [*]* (**) **() **[] *(*) *[*] (()) ()() ()[] ([]) [**] [()] [[]] []() [][] *()* *[]*

3
Số lượng mục trong đầu ra là A025235
Gabriel Benamy

@GabrielBenamy À. Tôi đã tự hỏi liệu điều đó đã được xem xét trước đó. Hấp dẫn.
Esolanging Fruit

2
Điều kiện chiến thắng là gì? Tôi giả sử chương trình ngắn nhất (mã golf).
Zgarb


1
Vì mọi người đều cho rằng đây là môn đánh gôn, tôi sẽ gắn thẻ thử thách cho phù hợp (vì nếu không nó sẽ khiến tất cả các câu trả lời hiện tại có phần vô nghĩa). Nếu bạn dự định một tiêu chí chiến thắng khác, bạn có thể xem xét đăng một thử thách mới.
Martin Ender

Câu trả lời:


3

Thạch, 29 byte

-3 byte nhờ @Jonathan ALLan

Xin vui lòng , thông báo cho tôi nếu có bất kỳ vấn đề / lỗi / lỗi hoặc byte tôi có thể loại bỏ!

“[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐLÐḟ

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

Các giải pháp trước đây tôi đã có:

“[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€Tị
“[(*)]”ṗµ¹ḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€Tị
“[(*)]”ṗµ¹ḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€×Jḟ0ị
“[(*)]”x⁸ṗ⁸Qµ¹ḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€×Jḟ0ị
“[(*)]”x⁸ṗ⁸Qµ¹µḟ”*œṣ⁾()Fœṣ⁾[]FµÐL€Ṇ€×Jḟ0ị
“[(*)]”x⁸ṗ⁸Qµ¹µḟ”*œṣ⁾()Fœṣ⁾[]FµÐLµ€Ṇ€×Jḟ0ị

Giải thích (Nỗ lực tốt nhất của tôi tại một mô tả):

Input n
“[(*)]”ṗ-All strings composed of "[(*)]" of length n
µḟ”*    -Filter out all occurences of "*"
œṣ⁾()   -Split at all occurences of "()"
F       -Flatten
œṣ⁾[]   -Split at all occurences of "[]"
F       -Flatten
µÐL     -Repeat that operation until it gives a duplicate result
Ðḟ      -Filter

Bạn có thể lưu ba byte bằng cách lọc ( “[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐLÐḟ)
Jonathan Allan

15

Prolog, 69 byte

s-->[];e,s.
e-->"*";"(",s,")";"[",s,"]".
b(N,A):-length(A,N),s(A,[]).

Một trong những tính chất thú vị nhất của Prolog là trong nhiều trường hợp, nó có khả năng chạy chương trình ngược; ví dụ: thay vì kiểm tra xem điều gì đó có đúng không, bạn có thể tạo tất cả các giải pháp cho điều đó đúng và thay vì kiểm tra độ dài của chuỗi, bạn có thể tạo tất cả các chuỗi có độ dài nhất định. (Một đặc tính hay khác của Prolog là nó yêu cầu khoảng trắng sau khi kết thúc mỗi định nghĩa vị ngữ và một dòng mới có thể được chèn với giá rẻ như một khoảng trắng; do đó, ngay cả các chương trình chơi gôn thường khá dễ đọc.)

Ở trên định nghĩa một vị từ (tương đương với một hàm) bđể kiểm tra xem một chuỗi có độ dài cho trước hay không và là "chuỗi giằng" như được định nghĩa trong câu hỏi. Cụ thể, nó thực hiện điều này thông qua hỗ trợ ngữ pháp / regex / mô hình khớp của Prolog cung cấp một số đường ngắn, đẹp để xác định loại biểu thức này (rõ ràng đây là tiêu chuẩn / di động, nhưng tôi không biết điều này trong khi ban đầu viết câu trả lời, và do đó giả sử câu trả lời sẽ chỉ hoạt động trên một triển khai Prolog; có vẻ như nó hoạt động trên mọi triển khai tuân thủ các tiêu chuẩn). Chương trình có thể được dịch sang tiếng Anh khá trực tiếp; hai dòng đầu tiên nói "một s là một chuỗi rỗng hoặc một e theo sau là một s ; một elà dấu hoa thị, hoặc s trong ngoặc đơn hoặc s trong ngoặc vuông ". Dòng thứ ba có thể được hiểu là" B của N có thể là A nếu A là danh sách có độ dài NAs theo sau là null chuỗi."

Tôi đã cẩn thận viết s(và do đó b) để chúng khớp với từng "chuỗi cú đúp" theo đúng một cách (đó là lý do cả hai sephải tồn tại, thay vì nhóm chúng thành một vị ngữ). Điều này làm cho cả hai hoàn toàn đảo ngược; do đó bcó thể được sử dụng để tạo ra tất cả các "chuỗi giằng" có độ dài nhất định, ngoài việc kiểm tra xem một chuỗi có phải là một chuỗi giằng có độ dài nhất định hay không (nó cũng có thể được sử dụng vòng thứ ba, để tìm ra độ dài của nẹp chuỗi, nhưng đó gần như chắc chắn là chế độ hoạt động ít hữu ích nhất của nó). Việc triển khai là đệ quy, ví dụ để tạo một s , mã sẽ tạo ra tất cả các e có thể không dài hơn độ dài yêu cầu của đầu ra và nối thêm tất cả các s có thểs phù hợp với không gian còn lại cho họ; bởi vì tôi đã chỉ định trước độ dài của đối số (trong b ), công cụ Prolog biết rằng nó không thể tạo đầu ra dài hơn độ dài cho trước, cho phép kết thúc đệ quy.

Đây là một ví dụ về chương trình đang hoạt động:

| ?- b(4,A),format("~s ",[A]),fail.
**** **() **[] *()* *(*) *[]* *[*] ()** ()() ()[] (*)* (**) (()) ([]) []** []() [][] [*]* [**] [()] [[]]

cảm giác như cần phải có một số chi phí cho cú pháp cần thiết để chỉ định xem bạn muốn chạy chương trình "chuyển tiếp" hay "ngược". perl trả 1 byte cho mỗi bit của thứ đó
Sparr

Chà, bạn có thể đưa ra một quy tắc rằng các đối số ở cuối luôn là giá trị trả về, sau đó đảo ngược thứ tự của các đối số để chỉ định cách bạn chạy chương trình. Điều khá phổ biến đối với các ngôn ngữ chơi gôn là tìm ra những gì họ nên làm một phần bằng cách xem liệu họ có được cung cấp bất kỳ đầu vào nào không, và đây là một nguyên tắc có thể so sánh được. Tuy nhiên, nói chung, thật khó để đưa ra các quy tắc áp dụng cho mọi ngôn ngữ có thể; chạy các nội dung như lengthappendmột trong hai cách là một phần cơ bản của ngôn ngữ và các chức năng của người dùng thường làm như vậy.

Ồ, hừm. Tôi giả sử có một số dấu hiệu trong ví dụ của bạn đã kích hoạt hành vi được đề cập.
Sparr

Không, đó hoàn toàn là do những lý lẽ được đưa ra. Trong chương trình trên, tôi viết length(A,N); nếu Nđược đưa ra và Akhông (sẽ xảy ra nếu vị ngữ được sử dụng theo cách được yêu cầu trong chương trình), lengthsẽ tạo ra một danh sách Abao gồm các Nphần tử không xác định. Sử dụng lengthđể đo chiều dài của danh sách có lẽ được sử dụng phổ biến hơn (mặc dù sử dụng nó "ngược" là khá phổ biến trong lập trình Prolog). Hầu hết các vị từ kết thúc hoạt động theo cùng một cách (lý do duy nhất họ không làm là nếu cố gắng đảo ngược chúng sẽ tạo ra một vòng lặp vô hạn, khá phổ biến).

1
@ ais523 -->và DCG nói chung là tiêu chuẩn ISO Prolog .
Gây tử vong vào

5

Haskell, 101 94 byte

7 byte được lưu bởi Zgarb!

b 0=[""]
b n=[x++y|k<-[1..n],x<-u k,y<-b$n-k]
u 1=["*"]
u n=[a:s++b|s<-b$n-2,a:b<-["()","[]"]]

Hầu như đơn giản, theo định nghĩa, nhưng với ""trường hợp di chuyển.

Sử dụng:

*Main> map b [0..3]
[[""],["*"],["**","()","[]"],["***","*()","*[]","()*","[]*","(*)","[*]"]]
*Main> length $ b 10
21595

(Tính toán thứ hai mất ít hơn một giây trên máy chậm.)

Tôi cũng muốn chia sẻ kết quả của một cách tiếp cận khác mà tôi đã nghĩ ra trong khi nghĩ về việc tạo các hàm. Nó định nghĩa một danh sách b các danh sách các chuỗi b!!ncó chứa tất cả các chuỗi có độ dài n. Tương tự, u!!nchứa tất cả các nguyên tử có kích thước n-1. Một điều tốt đẹp là mã không sử dụng bất kỳ số nào. Nó không hoàn toàn được đánh gôn: uicó thể được nội tuyến, và nó chắc chắn bỏ lỡ một vài cơ hội chơi gôn khác. Thật không may, có vẻ như nó không thể được làm ngắn hơn phiên bản đầu tiên, nhưng nó length $ b !! 10còn nhanh hơn nữa.

b=[""]:b%u
u=["*"]:map i b
i=concatMap(\s->['(':s++")",'[':s++"]"])
(b:c)%f=zipWith(++)[[x++y|x<-b,y<-e]|e<-f]([]:c%f)

Lưu hai byte với b$n-kb$n-2. Ngoài ra, trên dòng cuối cùng bạn có thể làm a:b<-["()","[]"]và trở lại a:s++b.
Zgarb

Ồ tôi muốn sử dụng ["()","[]"]nhưng không thể thấy cách cải thiện kích thước mã với nó. Cảm ơn!
Christian Sievers

4

Toán học, 116 byte

#<>""&/@Select[Characters@"*([)]"~Tuples~#,(#/."*"->Nothing//.{a___,"(",")",b___}|{a___,"[","]",b___}:>{a,b})=={}&]&

Giải trình

Characters@"*([)]"

Tìm các ký tự của chuỗi "*([)]", đưa ra List {"*", "(", "[", ")", "]"}.

... ~Tuples~#

Tìm các bộ dữ liệu của danh sách trên với chiều dài n.

(#/."*"->Nothing//.{a___,"(",")",b___}|{a___,"[","]",b___}:>{a,b})=={}&

Hàm Boolean chưa được đặt tên để tìm xem bộ dữ liệu có được cân bằng hay không:

#/."*"->Nothing

Xóa tất cả "*"trong đầu vào.

... //.{a___,"(",")",b___}|{a___,"[","]",b___}:>{a,b}

Nhiều lần xóa tất cả các lần xuất hiện liên tiếp "("")"hay "[""]"cho đến khi đầu vào không thay đổi.

... =={}

Kiểm tra xem kết quả có trống không List.

Select[ ... , ... ]

Tìm các bộ dữ liệu đưa ra Truekhi hàm Boolean được áp dụng.

#<>""&/@

Chuyển đổi từng Listký tự thành Strings.


2
Hơi bất ngờ, {x=a___,"(",")",y=b___}|{x,"[","]",y}dường như có tác dụng.
Martin Ender

4

Python 2, 128 byte

n=input()
for i in range(5**n):
 try:s=','.join('  "00([*])00"  '[i/5**j%5::5]for j in range(n));eval(s);print s[1::4]
 except:1

Các regex đệ quy vít - chúng tôi đang sử dụng trình phân tích cú pháp của Python! Để xác minh rằng, ví dụ, *(**[])*là một chuỗi ngoặc, chúng tôi làm như sau:

  1. Tạo một chuỗi như thế "*", (0,"*","*", [0,0] ,0) ,"*", trong đó mỗi ký tự thứ hai của bốn là một ký tự từ chuỗi ký tự và các ký tự còn lại được dán để biến điều này thành biểu thức Python tiềm năng.

  2. eval

  3. Nếu điều đó không gây ra lỗi, hãy in s[1::4](các ký tự chuỗi ký tự).

Các ký tự keo được chọn sao cho chuỗi tôi tạo là biểu thức Python hợp lệ khi và chỉ khi lấy mỗi ký tự thứ hai trong số bốn thì mang lại chuỗi ký tự hợp lệ.


2

PHP, 149 byte

for(;$argv[1]--;$l=$c,$c=[])foreach($l?:['']as$s)for($n=5;$n--;)$c[]=$s.'*()[]'[$n];echo join(' ',preg_grep('/^((\*|\[(?1)]|\((?1)\))(?1)?|)$/',$l));

Sử dụng tốt tạo ra tất cả có thể và sau đó phương pháp lọc. Sử dụng như:

php -r "for(;$argv[1]--;$l=$c,$c=[])foreach($l?:['']as$s)for($n=5;$n--;)$c[]=$s.'*()[]'[$n];echo join(' ',preg_grep('/^((\*|\[(?1)]|\((?1)\))(?1)?|)$/',$l));" 4

1

Python, 134 byte

from itertools import*
lambda n:[x for x in map(''.join,product('*()[]',repeat=n))if''==eval("x"+".replace('%s','')"*3%('*',(),[])*n)]

thay thế

Hàm không tên trả về danh sách các chuỗi có độ dài hợp lệ n.
Hình thành tất cả các nbộ dữ liệu độ dài của các ký tự *()[], nối chúng thành các chuỗi bằng cách sử dụng map(''.join,...)và các bộ lọc cho những bộ có dấu ngoặc cân bằng bằng cách xóa "cặp""*" , "()""[]"lần lượt nlần và kiểm tra xem kết quả là một chuỗi rỗng ( nlần là quá mức cần thiết, đặc biệt đối với "*"nhưng là người chơi gôn).


1

Võng mạc , 78 byte

Số lượng byte giả định mã hóa ISO 8859-1.

.+
$*
+%1`1
*$'¶$`($'¶$`)$'¶$`[$'¶$`]
%(`^
$';
)+`(\[]|\(\)|\*)(?=.*;)|^;

A`;

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

Giải trình

Tôi đang tạo tất cả các chuỗi có thể có độ dài 5 và sau đó tôi lọc ra các chuỗi không hợp lệ.

.+
$*

Điều này chuyển đổi đầu vào thành unary, sử dụng 1như là chữ số.

+%1`1
*$'¶$`($'¶$`)$'¶$`[$'¶$`]

Điều này lặp đi lặp lại ( +) thay thế cái đầu tiên ( 1) trong mỗi dòng ( %) theo cách nó tạo ra năm bản sao của dòng, một bản sao cho mỗi ký tự có thể. Điều này được thực hiện bằng cách sử dụng các thay thế tiền tố và hậu tố, $`$' để xây dựng phần còn lại của mỗi dòng.

Vòng lặp này dừng khi không có thêm 1 giây để thay thế. Tại thời điểm này, chúng tôi có tất cả các chuỗi độ dài có thể N, một chuỗi trên mỗi dòng.

%(`^
$';
)+`(\[]|\(\)|\*)(?=.*;)|^;

Hai giai đoạn này được thực hiện cho từng dòng riêng biệt ( %). Giai đoạn đầu tiên chỉ đơn giản là sao chép dòng, với một ;để tách hai bản sao.

Giai đoạn thứ hai là một vòng lặp ( +), mà liên tục loại bỏ [], ()hoặc *từ các bản sao đầu tiên của chuỗi, hoặc loại bỏ một dấu chấm phẩy ở đầu dòng (mà chỉ có thể sau khi chuỗi đã biến mất hoàn toàn).

A`;

Các chuỗi hợp lệ là những chuỗi không còn dấu chấm phẩy ở phía trước chúng, vì vậy chúng tôi chỉ cần loại bỏ tất cả các dòng ( A) có chứa dấu chấm phẩy.


Tôi đã thử onliny với đầu vào 5: ok. Với đầu vào 6, tôi nhận được một trang lỗi
edc65

@ edc65 Hoạt động với tôi, nhưng tất nhiên cách tiếp cận này không thực sự hiệu quả, nên mất vài giây. Bạn muốn nói đến loại trang lỗi nào?
Martin Ender

Đầu vào 5: trả lời trong 3 giây. Đầu vào 6: sau 7 giây, Bên trong hộp Đầu ra, tôi nhận được nguồn html của trang có thể là lỗi từ proxy của tôi. Nếu đó là thời gian chờ thì đó là thời gian chờ rất ngắn ... Tôi đã cố gắng lấy một trường hợp kiểm tra đúng cho đầu vào 6, vì tôi câu trả lời của tôi có vẻ ổn với đầu vào 5, nhưng sai từ 6 trở lên
edc65

@ edc65 Chắc chắn mất nhiều hơn 7 giây và thời gian chờ của TIO là một phút. Tôi chưa bao giờ thấy lỗi mà bạn mô tả, có thể đáng để đưa ra lỗi này trong trò chuyện TIO (hoặc nếu bạn thích trên gitter hoặc GitHub ). Đối với đầu ra tham chiếu, đây là những gì tôi nhận được cho đầu vào 6: pastebin.com/WmmPPmrc (Đầu vào 7 mất hơn một phút.)
Martin Ender

1

Python 3.5, 146 byte

import re;from itertools import*;lambda f:{i for i in map(''.join,permutations("[()]*"*f,f))if re.fullmatch("(\**\[\**\]\**|\**\(\**\)\**)*|\**",i)}

Rất dài so với các câu trả lời khác, nhưng câu trả lời ngắn nhất hiện tại tôi có thể tìm thấy. Nó ở dạng hàm lambda ẩn danh và do đó phải được gọi theo định dạng

print(<Function Name>(<Integer>))

Kết quả đầu ra một Python bộ của thứ tự chuỗi đại diện cho tất cả các chuỗi có thể có của độ dài đầu vào.

Ví dụ: giả sử hàm trên được đặt tên G, việc gọi G(3)sẽ dẫn đến kết quả đầu ra sau:

{'[*]', '*()', '*[]', '(*)', '***', '[]*', '()*'}

Dùng thử trực tuyến! (Ý)


Tuy nhiên, nếu như tôi, bạn không thực sự là người thích đơn giản hóa mọi thứ bằng cách sử dụng các công cụ tích hợp, thì đây là câu trả lời ban đầu của riêng tôi không sử dụng bất kỳ thư viện bên ngoài nào để tìm hoán vị và hiện đang đứng ở mức khổng lồ 288 237 byte :

import re;D=lambda f:f and"for %s in range(%d)"%(chr(64+f),5)+D(f-1)or'';lambda g:[i for i in eval('["".join(('+''.join('"[()]*"['+chr(o)+'],'for o in range(65,65+g))+'))'+D(g)+']')if re.fullmatch("(\**\[\**\]\**|\**\(\**\)\**)*|\**",i)]

Một lần nữa, giống như câu trả lời cạnh tranh, câu trả lời này ở dạng hàm lambda và do đó cũng phải được gọi theo định dạng

print(<Function Name>(<Integer>))

Và đưa ra một danh sách Python các chuỗi chưa sắp xếp đại diện cho tất cả các chuỗi ngoặc của độ dài đầu vào. Ví dụ: nếu lambda được gọi là G(3), thì lần này đầu ra sẽ là như sau:

['*()', '(*)', '*[]', '[*]', '()*', '[]*', '***']

Ngoài ra, chương trình này cũng là nhanh hơn rất nhiều so với câu trả lời khác của tôi, có thể tìm thấy tất cả cú đúp-chuỗi có độ dài 11trong khoảng 115 giây , những độ dài 10trong khoảng 19 giây , những độ dài 9trong khoảng 4 giây , và những người có độ dài 8trong khoảng 0,73 giây trên máy của tôi, trong khi câu trả lời cạnh tranh của tôi mất nhiều thời gian hơn 115 giây cho đầu vào 6.

Dùng thử trực tuyến! (Ý)


0

05AB1E, 23 byte

…[(*.∞sãʒ'*м„()„[]‚õ:õQ

Một số tính năng này có thể đã được triển khai sau khi câu hỏi được đăng. Mọi góp ý đều được chào đón!

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

Làm sao?

…[(* - the string '[(*'
.∞ - intersected mirror, '[(*'=>'[(*)]'
s - swap the top two items, which moves the input to the top
ã - cartesian power
ʒ ...  - filter by this code:
  '*м      - remove all occurrences of '*'
  „()„[]‚  - the array ["()","[]"]
  õ        - the empty string ""
  :        - infinite replacement (this repeatedly removes "()", "[]", and "*" from the string
  õQ       - test equality with the empty string

Tôi không biết 05AB1E, nhưng cũng không *thể nằm trong mảng loại bỏ? Và õQkiểm tra có thể được thay thế bằng một cái gì đó như KHÔNG?
Esolanging Fruit

Đề xuất đầu tiên sẽ không lưu bất kỳ byte nào: '*м„()„[]‚õ:vs „()„[]‚'*«õ:(không được kiểm tra), vì không có lệnh nối 3 giá trị AFAIK. Cái thứ hai sẽ không hoạt động vì không có cái nào hoạt động như thế trên chuỗi, AFAIK. (Nơi AFAIK đại diện cho "theo như tôi biết")
Zacharý
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.