連動ブラケット


30

()[]{}<>4つのそれぞれのブラケットタイプが一致するように配置された各文字の1つを含む8バイト文字列を取り込むプログラムまたは関数を記述します。たとえば]<([){}>、角括弧が一致しないため、入力は無効です(ただし、他のすべては一致します)。

から整数を出力0する6か、4つのブラケットタイプの6つの可能な組み合わせのどれだけがインターロックされるかを示します。ブラケットタイプペアは、1つのタイプのブラケットがもう1つのタイプのブラケットの間にちょうど1つある場合、インターロックされていると見なされます。そう([)][(])連動しているが()[][]()([])、と[()]ではありません。

バイト単位の最短コードが優先されます。

入出力の例

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

回答:


17

CJam、18歳

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

ゴルフのアイデアをお寄せいただきありがとうございますisaacg :)
オンラインで試すか、すべての例を試す

説明:

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
ああ、だからあなたはCJamを作成した人ですか?? CJamの回答に打ちのめされた、私が失ったすべての答えをあなたは私に負っています!;)
kirbyfan64sos

6
@ kirbyfan64sosよく、あなたが勝ちたいなら、あなたもそれを学び始めた方が良いでしょう:)
aditsu

9
7~f&?私はすでにこの答えが好きです、そして、私はそれの残りさえ読んでいません。
デニス

11

Python 2、163バイト

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

これは、一致するブラケットの各ペアの間のものを調べ、存在する個々の左または右ブラケットの数をカウントします。これらの合計を2で割ったものが出力です。

私よりも優れたゴルファーがもっとゴルフをすることができると確信しています。


31
まあ、それは起こった。Calvinが回答を投稿しました。終わりの時が来ました。
アレックスA.

4

GNU sed -r、147

出力は、このメタアンサーごとに単項です。

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

注:正しいスコアを取得するには、\t実際のtab文字に置き換えてください。ただし、プログラムはGNU sedでどちらの方法でも機能します。

オンラインでお試しください


3

Perl、77バイト

76コード+ 1スイッチ

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

STDINから入力を受け取り、入力ごとにプログラムを新たに起動する必要があります。

説明

  1. すべての閉じブラケットを、対応する開いたブラケットに置き換えます(y/.../.../)。
  2. 次に、入力文字列(for$x...)内のすべての文字について、文字のカウンターをインクリメントします($h{$x}++)。
  3. これが文字を見るのが2回目である場合、2つの出現の間の距離を取得し(length $1)、文字列からこの文字の両方の出現を削除します。たとえば、文字列がの場合、([{([{<<2つの文字が[あり{、2つ(のsの間にあります。後に(Sが処理され、文字列になり[{[{<<、我々は総数(に2を追加$z連動ブラケット)。
  4. 結果は$z$_=$z)から取得されます

3

Pyth、20バイト

JmC/CdTzlsm@FPcsJd{J

テストスイート

JmC/CdTz:まず、これは、各入力文字をCd10(/ T)で割った文字コード()にマップすることにより、各シンボルペアを単一の文字に変換します。結果の数値は、後で明らかにするために、文字に変換されます(C)。結果の文字のリストはに保存されJます。

lsm@FPcsJd{J:ここで、J{J)の一意の文字をマッピングします。J現在の文字を区切り文字(csJd)として使用して連結して形成された文字列を切り刻むことから始めます。ブラケットのペアは、2番目のグループと最初または3番目のグループのいずれかに表示される場合、現在のペアと重なります。二重カウントを避けるために、最初と2番目のグループケースのみをカウントします。したがって、3番目のグループ(P)を削除し、残りのグループの交点()を取得し@Fます。最後に、オーバーラップ文字を連結し(s)、結果の長さを出力します(l)。


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)

私のCJamソリューションに大まかに基づいています。


3

網膜128の 108 64 62 55バイト

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

where <empty>は空の末尾の行を表します。カウントのために、各行を個別のファイルに入れ\n、実際の改行文字に置き換えます。便宜上、この同等のコードを-s単一ファイルのフラグとともに使用できます。

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

出力は単項です。

説明

1つ目(は、反復が文字列の変更を停止するまでループ内のコード全体を実行するようRetinaに指示します。この場合、各ブラケットタイプに1回ずつ、常に4回繰り返されます。

T`)]>}`([<{

これにより、各閉じ括弧が対応する開き括弧に単純に変換されるため、後で簡単な後方参照で対応する括弧を一致させることができます。(この段階は、最初の反復の後はノーオペレーションになります。ループに含まれるのは、Tすでにバックティックが必要であるため、追加する(コストは2バイトではなく1バイトのみです。)

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

これにより、ブラケットの左端のペアが改行に置き換えられます。カウント用のループの後半で追加\Dする1s とブラケットを区別するために使用します。(.*)唯一の対が交換されたエンド性を保証で(マッチが重複することができないため)。

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

正規表現全体が先読みされているため、これはpositionと一致します。より具体的には、それは、改行に変えたばかりの他のブラケットで区切られたブラケットの各ペアの1つの位置に一致します。1これらの各位置にA が挿入されます。1sをそのまま残しておくことができます。これは、他の正規表現に影響を与えないためです(\Dsが誤ってそれらを一致させないようにするためです)。

\n
<empty>

最後に、改行(つまり、現在のタイプのブラケットのプレースホルダー)を削除します-これは、残りの問題を3つのタイプのブラケットのみを含む長さ6の文字列に減らしたことを意味しますが、それ以外はまったく同じように機能します。

最後に、1挿入したs のみが残り、その量はインターロックブラケットの数に正確に対応します。


2

JavaScript(ES7)、121 117バイト

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

ワオ。それは楽しかった。このチャレンジが最初に出たとき、私は答えのアイデアをスケッチしましたが、それは150バイト以上の長さでした。昨日、ノートブックでこのアイデアに出くわし、完全にゴルフをするまで考えることをやめないと決めました。最終的に2つのまったく新しいアルゴリズムを作成しました。最初のアルゴリズムは、25バイト前後の大量のビットハッキングでゴルフした後、数バイト短くなりました。

使い方

まず、変数を設定するabします0aは、現在内部にあるブラケットペアの4 bビットバイナリ配列であり、ブラケットペアが互いにリンクされている16ビットバイナリ配列です。

次に、各文字を通じて、私たちのループcではx、各文字d'0123'。最初に、ブラケットのタイプを決定ce=c.charCodeAt()/26-1|0ます。各ブラケットタイプの10進文字コードは次のとおりです。

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

26で除算し、1を減算し、フローリングすることにより、これらをそれぞれ0、1、2、および3にマッピングします。

次に、この数値がの現在の値と等しいかどうかを確認しますd。そうである場合、dthブラケットタイプを入力または終了するため、でdthビットを反転aa^=1<<dます。それはありませんが、我々は場合はあるの内側d番目のブラケットの種類、我々は反転する必要があるeでビット目dの第4ビットセクションb。これは次のように行われます。

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

(a>>d&1)dthビットを返しますadthブラケット型の中にいる場合、これは1を返します。それ以外の場合は、0を返します。次に、d*4+eビットを左にシフトbし、結果をXOR します。dthブラケット型の内側にいる場合、これd*4+eb;のthビットをXORします。そうでなければ、何もしません。

すべてのループの最後にb、目的の戻り値の2倍に等しい1ビットの数が含まれます。ただし、これが何ビットかを把握する必要があります。それがサブ機能のf出番です:

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

Ifはy0で、これは単にそうでなければ0を返す、それが最後の少し取るyとしy%2、その後、すべてが、最後のビットを実行した結果追加しy、再びスルー機能を。例えば:

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

bこの関数を実行し、結果を2で割ると、答えがあります。


1

Oracle SQL 11.2、206バイト

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;

ゴルフをしていない:

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  
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.