Kilitleme dirsekleri


30

()[]{}<>İlgili dört braket türünün eşleşeceği şekilde düzenlenmiş karakterlerin her birini içeren sekiz baytlık bir dize alan bir program veya işlev yazın . Örneğin ]<([){}>, köşeli parantezlerin eşleşmemesi nedeniyle geçersiz giriş (diğerlerinin tümü yapsa da).

Baskı veya bir tamsayı dönmek 0için 6dört dirsek türleri muhtemel altı eşleşmelerine birçok birbirine nasıl olduğunu gösterir. Braket tipi çiftler, bir türe ait tam olarak bir braket diğer tekil braketler arasında meydana gelirse kilitlenmiş olarak kabul edilir. Yani ([)]ve [(])birbirine kilitli ama ()[], [](), ([]), ve [()]değildir.

Bayt cinsinden en kısa kod kazanır.

Giriş / Çıkış Örnekleri

()[]{}<> : 0
([{<>}]) : 0
<>{[]}() : 0
{<>([])} : 0
<(>)[{}] : 1
<[({)}]> : 1
[{<}]>() : 2
{<>([}]) : 2
<{(>})[] : 3
[(]<){>} : 3
<([>{)}] : 4
(<{[>})] : 4
(<[{)>}] : 5
<{[(>})] : 5
[{<(]}>) : 6
(<{[)>}] : 6

Yanıtlar:


17

CJam, 18

l7~f&_f{\/~;&}s,2/

Bazı golf fikirleri için teşekkürler isaacg :)
Çevrimiçi deneyin ya da tüm örnekleri deneyin

Açıklama:

l         read a line of input
7~f&      clear the lowest 3 bits of each character
           the goal is to convert brackets of the same type to the same char
_         duplicate the resulting string, let's call it S
f{…}      for each character in S, and S (the char and S are pushed every time)
  \       swap the character with S
  /       split S around that character, resulting in 3 pieces:
           before, between, after
  ~       dump the pieces on the stack
  ;       pop the last piece
  &       intersect the first 2 pieces
          after the loop, we have an array of strings
          containing the chars interlocking to the left with each char of S
s         join all the string into one string
,         get the string length
2/        divide by 2, because S has duplicated characters

1
Demek CJam’ı yaratan adamsın? Kaybettiğim tüm cevaplar için, CJam cevapları tarafından dövülen bana borçlusun! ;)
kirbyfan64sos


9
7~f&? Bu cevabı çok beğendim ve geri kalanını bile okumadım.
Dennis,

11

Python 2,160 bayt

def f(b,e='([{<)]}>',q=range(4)):
 b=[b[b.index(e[j])+1:b.index(e[j+4])]for j in q]
 print sum(sum(abs(b[k].count(e[j])-b[k].count(e[j+4]))for j in q)for k in q)/2

Bu, eşleşen her bir parantez çifti arasındaki eşyaya bakar ve mevcut bireysel sol ya da sağ parantezlerin sayısını sayar. Bunların toplamı ikiye bölünerek çıktısı alınır.

Eminim ki benden çok daha iyi golfçüler tarafından golf oynayabilir.


31
Evet, oldu. Calvin cevap verdi. Bitiş zamanları üzerimizde.
Alex A.

4

GNU sed -r, 147

Çıktı, bu meta cevaba göre aynı durumda .

y/([{</)]}>/
s/.*/\t& & & & /
:b
y/)]}>/]}>)/
s/\S*>(\S*)>\S* /\1\t/
t
s/\S* //
:
s/(\t\S*)(\S)(\S*)\2(\S*\t)/\1\3\4/
t
s/\S *$/&/
tb
s/\s//g
s/../1/g

Not: Doğru puanı almak için \tgerçek tabkarakterlerle değiştirin . Ancak, program GNU sed ile birlikte çalışacaktır.

Çevrimiçi deneyin .


3

Perl, 77 bayt

76 kod + 1 anahtarı

perl -pe 'y/)]}>/([{</;for$x(/./g){$h{$x="\\$x"}++&&s!$x(.*)$x!$z+=length$1,$1!e}$_=$z'

STDIN'den girdi alır ve her girdi için programın yeni başlatılması gerekir.

açıklama

  1. Tüm kapatma braketlerini açık meslektaşları ( y/.../.../) ile değiştirin.
  2. Ardından, girdi dizisindeki ( for$x...) her karakter için, ( $h{$x}++) karakteri için bir sayaç artırın .
  3. Eğer bu karakteri ikinci kez görüyorsanız, iki occurances ( length $1) arasındaki mesafeyi alın ve bu karakterin her iki oluşumunu string'den kaldırın. Örneğin, dize olsaydı, ([{([{<<iki karakter var [ve {ikisi arasında (. Sonra (s işlenir, dizi haline [{[{<<ve toplam sayısı (2 ila eklemek $zbirbirine dirseklerin).
  4. Sonuç $z( $_=$z) sitesinden alınmıştır.

3

Pyth, 20 bayt

JmC/CdTzlsm@FPcsJd{J

Test odası

JmC/CdTz: Öncelikle, bu, her bir sembol çiftini, her giriş karakterini karakter koduna ( Cd) bölünmüş 10 ( / T) ' a eşleştirerek tek bir karaktere dönüştürür; bu, her bir çift için aynıdır, ancak tüm çiftler arasında farklıdır. Elde edilen sayı, daha sonra ortaya konulacak amaçlar için tekrar bir karaktere dönüştürülür ( C). Karakterlerin çıkan liste kaydedilir J.

lsm@FPcsJd{J: Şimdi, J( {J) içindeki benzersiz karakterlerin haritasını çıkardık . JGeçerli karakteri delimeter ( csJd) kullanarak birleştirerek oluşan dizgiyi doğrayarak başlıyoruz . İkinci grupta ve birinci veya üçüncü grupta görünüyorsa, bir çift parantez geçerli çiftin üstüne gelir. İkili sayımı önlemek için birinci ve ikinci grup vakasını sayıyoruz. Böylece, üçüncü grubu ( P) kaldırır ve geri kalan grupların ( @F) kesişimini alırız . Son olarak, üst üste gelen karakterleri ( s) birleştiririz ve resut'un ( l) uzunluğunu yazdırırız .


3

Python 3, 107

t=0
s=""
for x in input():s+=chr(ord(x)&~7)
for x in s:a=s.split(x);t+=len(set(a[0])&set(a[1]))
print(t//2)

Gevşek olarak CJam çözümüme dayanıyor.


3

Retina , 128 108 64 62 55 bayt

(T`)]>}`([<{
(\D)(.*)\1(.*)
\n$2\n$3
(?=(\D).*\n.*\1)
1
\n
<empty>

Burada <empty>, boş bir arka çizgisini temsil eder. Sayma amacıyla, her satırı ayrı bir dosyaya koyun ve \ngerçek satır besleme karakterleriyle değiştirin. Kolaylık olması için, bu eşdeğer kodu -stek bir dosyadaki bayrakla kullanabilirsiniz :

(T`)]>}`([<{
(\D)(.*)\1(.*)
#$2#$3
(?=(\D)[^#]*#[^#]*\1)
1
#
<empty>

Çıktı tekdüze .

açıklama

Birincisi (, Retina'ya, bir yineleme dizeyi değiştirmeyi bırakana kadar kodun tamamını bir döngüde çalıştırmasını söyler. Bu durumda, her braket tipi için her zaman bir kez dört kez tekrar eder.

T`)]>}`([<{

Bu, her bir kapatma braketini ilgili açılış braketine çevirir, böylece ilgili braketleri daha sonra basit bir geri dönüş ile eşleştirebiliriz. (Bu aşama ilk yinelemeden sonra işlem dışı kalır. Sadece döngüye dahil edilir, çünkü Tzaten bir backtick gerektirir, bu nedenle (iki bayt yerine yalnızca bir maliyet eklenir .)

(\D)(.*)\1(.*)
\n$2\n$3

Bu, en soldaki parantez çiftini yeni satırlarla değiştirir. Biz kullanmak \Ddestekleri ayırt etmek 1biz sayımı için döngüde daha sonra eklemek s. (.*)Sadece bir çift ikame uç aktarımı sağlar (çünkü bir değil örtüşme olabilir).

(?=(\D).*\n.*\1)
1

Tüm regex bir bakışta, bu nedenle bu bir pozisyon ile eşleşir . Daha özel olarak, yeni satırlara çevirdiğimiz diğer parantezlerle ayrılmış her bir parantez çifti için bir konumla eşleşir. 1Bu pozisyonların her birine A yerleştirilir. Bunları 1orada bırakabiliriz , çünkü diğer regex'lerin hiçbirini etkilemiyorlar (çünkü \Dyanlışlıkla onları eşleştirmememizi sağlıyorlar).

\n
<empty>

Son olarak, yeni satırları kaldırırız (yani, şu anki ayraç türü için yer tutucular) - bu, kalan sorunu yalnızca 3 tür ayraç içeren bir uzunluk 6'ya düşürdüğümüz anlamına gelir, ancak tam olarak aynı şekilde çalışır.

Sonunda, sadece 1eklediğimiz s'ler bırakılacaktır ve bunların miktarları birbirine tam olarak bağlanan parantez sayısına karşılık gelir.


2

JavaScript (ES7), 121 117 bayt

x=>(a=b=0,[for(c of x)for(d of'1234')(e=c.charCodeAt()/26|0)==d?a^=1<<d:b^=(a>>d&1)<<d*4+e],f=y=>y&&y%2+f(y>>1))(b)/2

Vay. Bu eğlenceliydi. Bu meydan okuma ilk ortaya çıktığında bir cevap fikri çizdim, ancak 150 bayttan fazlaydı ve golf oynamak için çaba sarf etmek istemedim. Dün bu fikri rastladım ve tamamen golf oynayana kadar düşünmeyi bırakmayacağına karar verdim. İki yeni bit algoritma yazdım, bunlardan ilki, tonlarca bit hackiyle 25 bayt civarında golf oynadıktan sonra birkaç bayt daha kısa oldu.

Nasıl çalışır

İlk önce ave bile değişkenleri belirledik 0. aşu anda içinde bulunduğumuz parantez çiftlerinin bulunduğu 4 bitlik bir ikili dizidir veb parantez çiftlerinin bulunduğu 4 bitlik bir ikili dizi ve parantez çiftlerinin birbirine bağlandığı 16 bitlik bir ikili dizidir.

Daha sonra, ciçindeki her karakterin içinde xve her karakterin diçinde dönüyoruz '0123'. İlk önce ne tür bir braketin colduğunu belirleriz e=c.charCodeAt()/26-1|0. Her ayraç türünün ondalık karakter kodları aşağıdaki gibidir:

() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125

26'ya bölerek, 1'i çıkararak ve döşemeyi sıralayarak bunları sırasıyla 0, 1, 2 ve 3 ile eşleştiririz.

Daha sonra bu sayının şu anki değere eşit olup olmadığını kontrol edeceğiz d. Eğer durum bu ise, biz ya giriyoruz ya çıkarken dbiz çevirmek böylece, inci braket tipi dde inci biti aile a^=1<<d. O değil, ama biz ise şunlardır içeride dinci braket tipi, biz çevirmek gerekir eiçinde inci biti dth 4 bitlik bölüm b. Bu böyle yapılır:

b^=(a>>d&1)<<d*4+e

(a>>d&1)dTh bitini döndürür a. Eğer dparantez tipinin içindeysek , bu 1 döndürür; aksi takdirde, 0 döndürür. Sonra, bu sola d*4+ebitler, XOR bsonuçla döneriz . Eğer dparantez tipinin içindeysek , bu XOR d*4+eth's bit b; Aksi takdirde, hiçbir şey yapmaz.

Tüm döngünün sonunda b, istenen dönüş değerinin iki katına eşit bir miktar 1 bit içerecektir. Fakat bunun kaç bit olduğunu bulmamız gerekiyor. Alt fonksiyonun girdiği fyer:

f=y=>y&&y%2+f(y>>1)

Eğer y0'dır, bu basitçe 0. Aksi takdirde, son bit alır döndürür yile y%2daha sonra tüm ama son bit çalışan sonucunu ekler, ytekrar işlevi aracılığıyla. Örneğin:

f(y)         => y && y%2 + f(y>>1)
f(0b1001101) =>       1  + f(0b100110) = 4
f(0b100110)  =>       0  + f(0b10011)  = 3
f(0b10011)   =>       1  + f(0b1001)   = 3
f(0b1001)    =>       1  + f(0b100)    = 2
f(0b100)     =>       0  + f(0b10)     = 1
f(0b10)      =>       0  + f(0b1)      = 1
f(0b1)       =>       1  + f(0b0)      = 1
f(0b0)       => 0                      = 0

Biz koşmak bbu işlev sayesinde sonucu 2 ile bölmek ve cevabımız yoktur.


1

Oracle SQL 11.2, 206 bayt

WITH v AS(SELECT b,MIN(p)i,MAX(p)a FROM(SELECT SUBSTR(TRANSLATE(:1,'])>}','[(<{'),LEVEL,1)b,LEVEL p FROM DUAL CONNECT BY LEVEL<9)GROUP BY b)SELECT COUNT(*)FROM v x,v y WHERE x.i<y.i AND x.a<y.a AND y.i<x.a;

Golfsüz:

WITH v AS( -- Compute min and max pos for each bracket type
           SELECT b,MIN(p)i,MAX(p)a 
           FROM   ( -- replace ending brackets by opening brakets and split the string  
                    SELECT SUBSTR(TRANSLATE(:1,'])>}','[(<{'),LEVEL,1)b,LEVEL p 
                    FROM DUAL 
                    CONNECT BY LEVEL<9
                  )
           GROUP BY b
         )
SELECT COUNT(*)
FROM   v x,v y
WHERE  x.i<y.i AND x.a<y.a AND y.i<x.a -- Apply restrictions for interlocking brackets  
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.