N uzunluğundaki tüm küme dizelerini oluştur


16

Bir küme ayracı dizesi, *()[]ayraçların doğru eşleştiği karakterlerden oluşan bir dize olarak tanımlanır :

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

Bu geçerli bir ayraç dizesi:

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

Ancak bunlar:

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

Göreviniz, pozitif bir tamsayı verildiğinde nbir sayıyı girdi olarak alan ve geçerli tüm ayraç dizeleri çıktısını veren (veya döndüren) bir program (veya işlev) yazmaktır n.

Özellikler

  • Dizeleri herhangi bir sırayla çıktılayabilirsiniz.
  • Farklı bir karakterle ayrılmış bir liste veya dize olarak çıktı alabilirsiniz.
  • Programınız 0'ı doğru işlemelidir. Boş dize olan 0 uzunluğunda 1 olası parantez dizesi vardır "".
  • Bu , bu yüzden bayt cinsinden ölçülen en kısa geçerli cevap kazanır.

Test Durumları

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


@GabrielBenamy Ah. Daha önce bakılıp bakılmadığını merak ediyordum. İlginç.
Esolanging Fruit

2
Kazanan koşul nedir? En kısa programı varsayıyorum (kod golf).
Zgarb


1
Herkes bu kod golf olduğunu varsayar, ben buna göre (aksi takdirde mevcut tüm cevapları biraz anlamsız yapacak gibi) meydan etiketleyecektir. Farklı bir kazanan kriter istediyseniz, yeni bir meydan okuma yayınlamayı düşünebilirsiniz.
Martin Ender

Yanıtlar:


3

Jöle, 29 bayt

@JonathanAllan sayesinde -3 bayt

Lütfen , herhangi bir sorun / hata / hata veya bayt varsa beni uyar!

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

Çevrimiçi deneyin!

Sahip olduğum önceki çözüm (ler):

“[(*)]”ṗµḟ”*œṣ⁾()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ị

Açıklama (Bir açıklamaya yönelik en iyi girişimim):

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

Filtreleme kullanarak üç bayt kaydedebilirsiniz ( “[(*)]”ṗµḟ”*œṣ⁾()Fœṣ⁾[]FµÐLÐḟ)
Jonathan Allan

15

Prolog, 69 bayt

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

Prolog'un en ilginç özelliklerinden biri, çoğu durumda bir programı geriye doğru çalıştırabilmesidir; örneğin, bir şeyin doğru olup olmadığını test etmek yerine, doğru olduğu tüm çözümleri üretebilir ve bir dizenin uzunluğunu kontrol etmek yerine, belirli bir uzunlukta tüm dizeleri oluşturabilirsiniz. (Prolog'un bir başka güzel özelliği, her yüklem tanımının bitiminden sonra boşluk gerektirmesi ve yeni satırın boşluk kadar ucuza eklenebilmesidir; bu nedenle golf programları bile genellikle oldukça okunabilir.)

Yukarıda, bir bdizenin belirli bir uzunluğa sahip olup olmadığını ve soruda tanımlandığı gibi bir "küme dizesi" olup olmadığını test eden bir yüklem (bir fonksiyonun eşdeğeri) tanımlanmaktadır. Özellikle, bu tür bir ifadeyi tanımlamak için güzel, kısa şeker veren Prolog'un dilbilgisi / regex / desen eşleştirme desteği ile bunu yapar (görünüşe göre bu standart / taşınabilirdir, ancak orijinal olarak cevabı yazarken bundan habersizdim ve böylece cevabın sadece bir Prolog uygulaması üzerinde işe yarayacağı varsayılmıştır; yine de standartlara uyan her uygulamada işe yarıyor gibi görünüyor). Program oldukça doğrudan İngilizce'ye çevrilebilir; İlk iki satır bir" demek s boş bir dizge ya da bir olduğu , e bir takiben s , bir Ebir yıldız işareti ya da bir olduğu s parantez içinde veya bir s köşeli parantez içinde "Üçüncü çizgi olarak yorumlanabilir" b arasında N olabilir bir eğer bir uzunluk ile bir liste N ve A , bir olduğunu s bir boş ardından dize."

Ben yazma için bazı hallettim s(ve dolayısıyla bonlar (her ikisi bunların sebeplerini tam olarak hangi bir şekilde her bir "bağ dizesini" eşleşecek böylece) sve edaha ziyade bir yüklemi ayırarak daha var olmaları gerekir). Bu onların her ikisini de tamamen geri dönüşümlü yapar; bu nedenle b, bir ipin belirli bir uzunlukta bir parantez ipi olup olmadığını test etmenin yanı sıra, belirli bir uzunluktaki tüm "parantez iplerini" oluşturmak için kullanılabilir (ayrıca parantezin uzunluğunu anlamak için üçüncü bir yol boyunca da kullanılabilir) ancak bu kesinlikle en az kullanışlı çalışma şeklidir). Uygulama bir oluşturmak için, örneğin özyinelemelidir s , kod tüm olası üretecektir e çıkışının gerekli uzunluğundan daha artık s ve tüm olası ekleme skalan alana sığacak olanlar; argümanın uzunluğunu önceden ( b içinde ) belirlediğim için, Prolog motoru, belirtilen uzunluktan daha uzun çıktı üretemeyeceğini bilir ve özyinelemenin sona ermesine izin verir.

Çalışan programa bir örnek:

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

programı "ileri" veya "geri" çalıştırmak isteyip istemediğinizi belirtmek için gereken sözdiziminde bir miktar maliyet olması gerektiği düşünülmektedir. perl bu tür her bit için 1 bayt öder
Sparr

Sonunda bağımsız değişkenlerin her zaman döndürülen değer olduğuna dair bir kural oluşturabilir, ardından programı hangi yönde çalıştırdığınızı belirtmek için bağımsız değişkenlerin sırasını tersine çevirebilirsiniz. Golf dillerinde, herhangi bir girdi verilip verilmediğine bakarak kısmen ne yapmaları gerektiğini anlamak oldukça yaygındır ve bu karşılaştırılabilir bir prensiptir. Bununla birlikte, genel olarak, olası her dil için geçerli kurallar oluşturmak zordur; gibi lengthve appendher iki yönde yerleşik yapıları çalıştırmak dilin temel bir parçasıdır ve kullanıcı işlevleri genellikle aynı şeyi yapar.

Oh, hmm. Örneğinizde söz konusu davranışı tetikleyen bazı göstergeler olduğunu varsaydım.
Sparr

Hayır, tamamen hangi argümanların verildiğinden kaynaklanıyor. Yukarıdaki programda length(A,N); eğer Nverilir ve A(yüklem programında istenen şekilde kullanılır eğer gerçekleşecek olan) değil, lengthbir listesini oluşturacaktır Aoluşan Nbilinmeyen unsurları. Kullanılması lengthiçin ölçmek listenin uzunluğunu (kullanmadan rağmen "geriye" Prolog programlama oldukça yaygındır) muhtemelen daha yaygın olarak kullanılır. Çoğu tahmin, aynı şekilde çalışmayı sağlar (bunu yapmamalarının tek nedeni, onları tersine çevirmeye çalışmak oldukça yaygın olan sonsuz bir döngü inşa etmesidir).

1
@ ais523 -->ve genel olarak DCG'ler standart ISO Prolog'dur .
13'te ölümcül

5

Haskell, 101 94 bayt

7 bayt Zgarb tarafından kaydedildi!

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<-["()","[]"]]

Tanımı izleyen neredeyse basit, ancak ""dava taşındı.

kullanın:

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

(İkinci hesaplama yavaş bir makinede bir saniyeden az sürer.)

Ayrıca, fonksiyon üretmeyi düşünürken ortaya koyduğum başka bir yaklaşımın sonucunu paylaşmak istiyorum. Tüm küme uzunluğu dizelerini içeren dizelerin listelerinin bir listesini tanımlar . Benzer şekilde, tüm boyut atomlarını içerir . Güzel bir şey, kodun herhangi bir sayı kullanmamasıdır. Tamamen golf değil: ve inline olabilir ve kesinlikle birkaç golf fırsatını kaçırır. Ne yazık ki, ilk versiyondan daha kısa yapılabilir gibi görünmüyor, ancak daha hızlı hesaplıyor .bb!!nnu!!nn-1uilength $ b !! 10

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)

İki bayt kaydet b$n-kve b$n-2. Ayrıca, son satırda yapabilir a:b<-["()","[]"]ve geri dönebilirsiniz a:s++b.
Zgarb

Oh kullanmak istedim ["()","[]"]ama onunla kod boyutunu artırmak için nasıl göremedim. Teşekkürler!
Christian Sievers

4

Mathematica, 116 bayt

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

açıklama

Characters@"*([)]"

Dizesinin karakterleri bulun "*([)]"vererek List {"*", "(", "[", ")", "]"}.

... ~Tuples~#

Yukarıdaki listenin tuples'lerini uzunluğunda bulun n.

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

Adın dengeli olup olmadığını bulmak için adlandırılmamış Boole işlevi:

#/."*"->Nothing

Girişteki tümünü sil "*".

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

Defalarca tüm ardışık oluşumları sil "("ve ")"ya "["ve "]"giriş değişmez kadar.

... =={}

Sonucun boş olup olmadığını kontrol edin List.

Select[ ... , ... ]

TrueBoole işlevi uygulandığında verilen tuples'ları bulun .

#<>""&/@

ListKarakterlerin her birini Strings'ye dönüştürün .


2
Biraz beklenmedik bir şekilde {x=a___,"(",")",y=b___}|{x,"[","]",y}çalışıyor gibi görünüyor.
Martin Ender

4

Python 2, 128 bayt

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

Vidalı yinelemeli normal ifadeler - Python'un ayrıştırıcısını kullanıyoruz! Örneğin, *(**[])*küme ayracı dizesi olduğunu doğrulamak için aşağıdakileri yaparız:

  1. Dördün "*", (0,"*","*", [0,0] ,0) ,"*"her ikinci karakterinin ayraç dizelerinden bir karakter olduğu ve geri kalan karakterlerin bunu potansiyel bir Python ifadesi yapmak için tutkal olduğu gibi bir dize yapın .

  2. eval o.

  3. Bu bir hata atmazsa, yazdır s[1::4](ayraç dizesi karakterleri).

Tutkal karakterleri yaptığım dize geçerli bir Python ifadesidir böylece toplanır ancak ve ancak dört verim geçerli bir bağ telli her saniye karakterini yaptırmayı eğer.


2

PHP, 149 bayt

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

Mümkün olan tüm eski ve sonra filtre yöntemini üretmek kullanır. Gibi kullanın:

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 bayt

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

repl.it

Geçerli uzunluk dizelerinin listesini döndüren adsız işlev n.
Formlar tüm uzunluğu nkarakterlerin küpe *()[]kullanarak dizeleri içine katılır map(''.join,...)"çiftleri" kaldırarak parantez dengelediyseniz olanlar için ve filtreler "*", "()"ve "[]"dönüş içinde n(süreleri ve sonuç boş dizesi olduğunu kontrol nsüreleri için özellikle, overkill "*"ama golfçüdür).


1

Retina , 78 bayt

Bayt sayımı ISO 8859-1 kodlamasını varsayar.

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

A`;

Çevrimiçi deneyin!

açıklama

Ben uzunluk 5 olası tüm dizeleri oluşturmak ve sonra geçersiz olanları filtre.

.+
$*

Bu 1, rakamı kullanarak girişi tekli olarak dönüştürür .

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

Bu +, ( 1) her satırdaki ( %) ilk ( ) öğeyi, satırın beş kopyasını, her olası karakter için bir tane olacak şekilde değiştirir. Bu önek ve son ek ikameleri kullanarak yapılır $`ve $'her bir hattın kalan oluşturmak için.

Değiştirilecek daha fazla 1s olmadığında bu döngü durur. Bu noktada N, her satırda bir tane olmak üzere tüm olası uzunluk dizelerine sahibiz .

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

Bu iki aşama her satır için ayrı ayrı yürütülür ( %). İlk aşama satırı ;kopyalar ve iki kopyayı ayırmak için bir.

İkinci aşamada bir halka (bir +sürekli kaldırır), [], ()ya da *dize ilk kopyasından, ya da (string tamamen yok sonra mümkün olan) satır başında bir noktalı virgül kaldırır.

A`;

Geçerli dizeler, artık önünde noktalı virgül bulunmayan dizelerdir, bu nedenle Anoktalı virgül içeren tüm satırları ( ) atarız.


Giriş 5 ile onliny denedim: Tamam. Giriş 6 ile bir hata sayfası aldım
edc65

@ edc65 Benim için çalışıyor, ancak elbette bu yaklaşım tam olarak verimli değil, bu yüzden birkaç saniye sürüyor. Ne tür bir hata sayfası demek istiyorsun?
Martin Ender

Giriş 5: 3 saniye içinde cevap. Giriş 6: 7 saniye sonra, Çıkış kutusunun içinde, proxy'imden muhtemelen bir hata sayfası olan şeyin html kaynağını alıyorum. Eğer bir zaman aşımı varsa, o zaman çok kısa bir zaman aşımı ... Cevabım giriş 5'e kadar tamam görünüyor, ancak 6 veya daha fazla yanlış görünüyor çünkü giriş 6 için doğru bir test çantası almaya çalışıyordum
edc65

@ edc65 Kesinlikle 7 saniyeden uzun sürüyor ve TIO'nun zaman aşımı bir dakika. Ben açıkladığınız hatayı görmedim, değer bu yetiştirme olabilir TIO sohbet (ya da isterseniz Gitter üzerinde veya GitHub'dan ). Referans çıktısı için, giriş 6 için aldığım şey: pastebin.com/WmmPPmrc (Giriş 7 bir dakikadan fazla sürüyor.)
Martin Ender

1

Python 3.5, 146 bayt

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

Diğer cevaplara kıyasla çok uzun, ama şu anda bulabildiğim en kısa cevap. Anonim bir lambda işlevi biçimindedir ve bu nedenle biçiminde çağrılmalıdır

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

Python Çıktıları grubu arasında düzensiz giriş uzunluğu mümkün olan tüm köşebent-dizeleri temsil dizeleri.

Örneğin, yukarıdaki işlevin adlandırıldığı varsayılarak G, çağrılması G(3)aşağıdaki çıktıyla sonuçlanır:

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

Çevrimiçi Deneyin! (Ideone)


Benim gibi, gerçekten yerleşik ins öğelerden basitleştirilmesi hayranıyım değildir, Ancak, daha sonra burada benimkisi orijinal cevap değil kullanarak herhangi permütasyon bulmak için dış kütüphaneleri ve şu anda bir kuyruklu ayakta 288 237 bayt :

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

Yine, rakip cevap gibi, bu bir lambda işlevi biçimindedir ve bu nedenle de formatta çağrılmalıdır.

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

Ve bir Python çıktılar liste ait ayıklanmamış girdi uzunluğunun tüm bağ-dizeleri temsil eden dizeleri. Örneğin, lambda şu şekilde çağrılsaydı G(3), bu sefer çıktı aşağıdaki gibi olurdu:

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

Ayrıca, bu bir çok uzunluğunun tüm bağ-dizeleri bulmak mümkün, daha hızlı benim diğer cevap daha da 11yaklaşık içinde 115 saniye uzunluğunda olanlar 10hakkında içinde 19 saniye uzunluğunda olanlar 9hakkında içinde 4 saniye ve uzunluğa sahip olanlardan 8içinde makinemde yaklaşık 0.73 saniye , rakip yanıtımın girişi ise 115 saniyeden çok daha uzun sürüyor 6.

Çevrimiçi Deneyin! (Ideone)


0

05AB1E, 23 bayt

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

Soru gönderildikten sonra bu özelliklerden bazıları uygulamaya konmuş olabilir. Herhangi bir öneri bekliyoruz!

Çevrimiçi deneyin!

Nasıl?

…[(* - 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

05AB1E bilmiyorum, ama *aynı zamanda kaldırma dizisinde olamazdı ? Ve õQçek DEĞİL gibi bir şey ile değiştirilebilir?
Esolanging Fruit

İlk öneri herhangi bir bayt kaydetmeyecektir: '*м„()„[]‚õ:vs „()„[]‚'*«õ:(test edilmedi), çünkü 3 değeri AFAIK birleştirmek için bir komut yoktur. İkincisi çalışmaz, çünkü AFAIK bir ipte böyle çalışacak hiçbir NOT yoktur. (Burada AFAIK "bildiğim kadarıyla" temsil eder)
Zacharý
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.