角かっこを作る


33

すべてのプログラマーは、括弧[]{}()<>が本当に楽しいことを知っています。この楽しさを悪化させるために、織り込まれたブラケットのグループをキュートでファジーな図に変換できます。

のように、バランスの取れた括弧を含む文字列があるとしましょう[{][<(]})>(())。ステップ1は、弦を時計回りに45度回転させることです。(Mathematicaでは、これはほとんどでできますRotate[ur_string,-pi/4])。最初のステップの結果は次のとおりです。

[
 {
  ]
   [
    <
     (
      ]
       }
        )
         >
          (
           (
            )
             )

次に、各文字の間に斜めのスペースを追加します。

[

  {

    ]

      [

        <

          (

            ]

              }

                )

                  >

                    (

                      (

                        )

                          )

次に、一番左のブラケットから始めて、ブラケットと犯罪のパートナーとの間に四角形を描きます。

+---+
|   |
| { |
|   |
+---+

      [

        <

          (

            ]

              }

                )

                  >

                    (

                      (

                        )

                          )

ブラケットの各ペアでこのプロセスを繰り返し+、必要に応じて以前の文字をs で上書きします。

+---+
|   |
| +-+---------+
| | |         |
+-+-+         |
  |           |
  |   [       |
  |           |
  |     <     |
  |           |
  |       (   |
  |           |
  |         ] |
  |           |
  +-----------+

                )

                  >

                    (

                      (

                        )

                          )

すべてがきれいで正方形になるまで続けます。

+---+
|   |
| +-+---------+
| | |         |
+-+-+         |
  |           |
  |   +-----+ |
  |   |     | |
  |   | +---+-+---+
  |   | |   | |   |
  |   | | +-+-+-+ |
  |   | | | | | | |
  |   +-+-+-+ | | |
  |     | |   | | |
  +-----+-+---+ | |
        | |     | |
        | +-----+ |
        |         |
        +---------+

                    +-----+
                    |     |
                    | +-+ |
                    | | | |
                    | +-+ |
                    |     |
                    +-----+

入力

入力は、バランスの取れたブラケットの単一行であり、他の文字はありません[]{}()<>。各ブラケットはの1つです。各タイプのブラケットは個別にバランスが取られますが、異なるタイプが重複する場合があります(これにより、四角が面白く見えます)。末尾の改行はオプションです。

出力

出力は、ブラケット文字列から生成されたインターロック正方形パターンになります。末尾のスペースと末尾の改行はオプションですが、先頭の空白があってはなりません。

ゴール

これはコードゴルフであり、バイト数が最も少なくなります。


1
同じ種類のブラケットのネストを処理する必要がありますか?たとえば、[[]]2つの正方形を重ねて出力できますか、それとも一方の正方形をもう一方の内側に出力する必要がありますか?
揮発性

2
1つの正方形が他の正方形の内側にあります。私の例を調整します。編集:完了。
PhiNotPi

回答:


7

JavaScript(ES6)、269 274 278 296 261バイト

保存された4バイトの編集 @Neil @Neil

x=>[...x].map(c=>{g.push([],[]),z='<{[(>}])'.indexOf(c);if(z>3)for(j=a=o[z-4].pop();j<=b;j++)S(j,a,'|'),S(j,b,'|'),S(a),S(b);else o[z].push(b);b+=2},S=(y,x=j,c='-')=>g[y][x]=g[y][x]?'+':c,o=[[],[],[],[]],g=[],b=0)&&g.map(r=>[...r].map(c=>c||' ').join``).join`
`

テスト

F=x=>[...x].map(c=>{g.push([],[]),z='<{[(>}])'.indexOf(c);if(z>3)for(j=a=o[z-4].pop();j<=b;j++)S(j,a,'|'),S(j,b,'|'),S(a),S(b);else o[z].push(b);b+=2},S=(y,x=j,c='-')=>g[y][x]=g[y][x]?'+':c,o=[[],[],[],[]],g=[],b=0)&&g.map(r=>[...r].map(c=>c||' ').join``).join`
`

// Less golfed
U=x=>(
  S = (y,x=j,c='-')=>g[y][x]=g[y][x]?'+':c,
  o = [[],[],[],[]],
  g = [],
  b = 0,
  [...x].map(c=>
  {
    g.push([],[]),
    z='<{[(>}])'.indexOf(c);
    if(z>3)
      for(j = a =o[z-4].pop(); j <= b; j++)
        S(j,a,'|'),
        S(j,b,'|'),
        S(a),
        S(b)
    else
      o[z].push(b);
    b += 2
  }),
  g.map(r=>
    [...r].map(c=>c||' ').join``
  ).join`\n`
)

function test() {
  O.textContent=F(I.value)
}

test()
Input:<input id=I value='[{][<(]})>(())' oninput='test()'>
<pre id=O></pre>


どうして[...r].map
ニール

さらに良いことに、[...r].map(c=>c||' ')
ニール

r.maprはスパース配列であり、mapは欠落している要素をスキップするため、@ Neilは使用できません。だから私は今、gを使用し、それは塗りつぶされています(そして出力には列と同じ数の行があります)
-edc65

2
私は言わなかったr.map、私が言った[...r].map、そして[...r]あなたがあなた自身を述べたように、まばらな配列ではありませんcodegolf.stackexchange.com/a/61505のコメント5
ニール・

@ニール私はそれを見逃した...それはいいヒントのようです、ありがとう
-edc65

4

Python 3、226

n,p,*t=0,[],0,[],[],[],[]
for b in input():
 r=t[ord(b)//30];r+=[n];n+=2
 if b in'])}>':p+=[r[-2:]];del r[-2:]
R=range(n-1)
for y in R:print(''.join(' -|+'[sum((y in q)+2*(x in q)for q in p if x>=q[0]<=y<=q[1]>=x)]for x in R))

。説明:

n,p,*t=0,[],0,[],[],[],[]   # n -> counter for input
                            # p -> bracket pairs
                            # t -> four stacks [unused, (), <>, [], {}]

for b in input():           # for each bracket b of input
  r=t[ord(b)//30];          # r -> alias for b's stack
  r+=[n];                   # push bracket's index
  n+=2                      # increase counter by 2 (to add diagonal gaps)

  if b in'])}>':            # if b is a closing bracket
    p+=[r[-2:]];            # pair the top 2 brackets on stack
    del r[-2:]              # pop them from stack

R=range(n-1)                # n-1 is now the width/height of output

for y in R:
  print(''.join(' -|+'[
    sum((y in{a,b})+2*(x in{a,b})for a,b in p if x>=a<=y<=b>=x)
  ]for x in R))

# three nested loops:
# 1) for each line y
#   2) for each character x
#     3) for each bracket pair (a, b)

if x>=a<=y<=b>=x
# if x or y isn't in the inclusive range [a, b], we can skip it

(y in{a,b})
# if y is a or b, then the character lies on a horizontal edge of that square
# so we add 1 to the sum

2*(x in{a,b})
# if x is a or b, then the character lies on a vertical edge of that square
# so we add 2 to the sum

' -|+'[sum()]
# if it lies on a single edge, the sum will be 1 or 2 -> '-' or '|'
# if it lies on two edges, the sum will be 1 + 2 == 3 -> '+'

最終行のブラケットペアをアンパックしないことで、2バイトを節約できます。
ボラティリティ

2

pb -449バイト

^w[B!0]{w[B=40]{b[39]}t[B]w[B!0]{w[B=T]{^b[1]}w[B=T+1]{^b[1]}w[B=T+2]{^b[2]}^[Y]^>}<[X]^w[B!1]{>}t[1]b[0]w[T!0]{>w[B=1]{t[T+1]b[0]}w[B=2]{t[T-1]b[0]}}b[3]vw[B!0]{>}^w[B!3]{b[0]<}b[0]vb[1]>[X]vv[X]b[43]t[X]^[Y]^<[X]w[B=0]{>}>[X]vv[X]b[43]w[Y!T-1]{vw[B=45]{b[43]}w[B=0]{b[124]}}vb[43]t[1]>w[B!43]{t[T+1]w[B=124]{b[43]}w[B=0]{b[45]}>}w[T!0]{^t[T-1]w[B=45]{b[43]}w[B=0]{b[124]}}w[B!43]{w[B=124]{b[43]}w[B=0]{b[45]}<}<[X]^[Y]^w[B=0]{>}b[0]>w[B=1]{b[0]>}}

私がこれを読んだとき、私はすべて興奮しました。なぜなら、私はある位置に直接印刷する言語を持っているからです!出力の配置に関するこの課題は、簡単で短いものでなければなりません!

それから私は、とにかくpbが長い風に吹かれたことを思い出しました。

コメント付き:

^w[B!0]{
    w[B=40]{b[39]}                       # change ( to ' to make closing bracket calculation work
    t[B]

    # this used to just find the first matching bracket
    # but then op clarified we had to use depth
    # whoops
    # <fix>

    w[B!0]{
        w[B=T]{^b[1]}                        # put a 1 above opening brackets of this type
        w[B=T+1]{^b[1]}                      # same as before, but ugly hack to make ( work
        w[B=T+2]{^b[2]}                      # put a 2 above closing brackets of this type
        ^[Y]^                                # return to input line
    >}
    <[X]^w[B!1]{>}t[1]b[0]               # set T to 1 above the opening bracket
    w[T!0]{>                             # until T (depth) == 0:
        w[B=1]{t[T+1]b[0]}                   # add 1 to T if 1
        w[B=2]{t[T-1]b[0]}                   # subtract 1 from T if 2
    }
    b[3]                                 # when T is 0, we've found the right one
    vw[B!0]{>}                           # go to the end of the input
    ^w[B!3]{b[0]<}b[0]v                  # clean up the row above
    # </fix>

    b[1]                                 # replace it with 1 so it's not confusing later
    >[X]vv[X]b[43]t[X]                   # put a + at its output position and save coord
    ^[Y]^<[X]w[B=0]{>}>[X]vv[X]b[43]     # put a + at opening bracket's output position
    w[Y!T-1]{v
        w[B=45]{b[43]}                       # replace - with +
        w[B=0]{b[124]}                       # otherwise put |
    }
    vb[43]                               # put a + at lower left corner
    t[1]                                 # count side length + 1
    >w[B!43]{
        t[T+1]
        w[B=124]{b[43]}                      # replace | with +
        w[B=0]{b[45]}                        # otherwise put -
    >}
    w[T!0]{^                             # create right side
        t[T-1]
        w[B=45]{b[43]}
        w[B=0]{b[124]}
    }
    w[B!43]{                             # create top side
        w[B=124]{b[43]}                      # this replacement saves us from putting the last + explicitly
                                             # which is why we counted the side length + 1, to get that 
                                             # extra char to replace
        w[B=0]{b[45]}
    <}
    <[X]^[Y]^w[B=0]{>}b[0]>w[B=1]{b[0]>}# Go to next character (skipping 1s)
}

私...ただ...できない
...-チョイス


1

ルビー、268

->z{a=(2..2*t=z.size).map{'  '*t}
g=->y,x{a[y][x]=(a[y][x-1]+a[y][x+1]).sum>64??+:?|}
2.times{|h|s=z*1
t.times{|i|c=s[i]
c>?$&&(j=s.index(c.tr('[]{}()<>','][}{)(><'))
(m=i*2).upto(n=j*2){|k|k%n>m ?g[k,m]+g[k,n]:h<1&&a[k][m..n]=?++?-*(n-m-1)+?+}
s[i]=s[j]=?!)}}
puts a}

テストプログラムに参加していない

f=->z{
  a=(2..2*t=z.size).map{'  '*t}                       #make an array of strings of spaces
  g=->y,x{a[y][x]=(a[y][x-1]+a[y][x+1]).sum>64??+:?|} #function for printing verticals: | if adjacent cells spaces (32+32) otherwise +

  2.times{|h|                                         #run through the array twice
    s=z*1                                             #make a duplicate of the input (*1 is a dummy operation to avoid passing just pointer)
    t.times{|i|                                       #for each index in input
    c=s[i]                                            #take the character
    c>?$&&(                                           #if ascii value higher than for $
      j=s.index(c.tr('[]{}()<>','][}{)(><'))          #it must be a braket so find its match
      (m=i*2).upto(n=j*2){|k|                         #loop through the relevant rows of array
        k%n>m ?g[k,m]+g[k,n]:                         #if k!=n and k!m draw verticals
        h<1&&a[k][m..n]=?++?-*(n-m-1)+?+              #otherwise draw horizontals (but only on 1st pass)
      }
      s[i]=s[j]=?!)                                   #we are done with this set of brackets, replace them with ! so they will be ignored in next call of index  
    }
  }
  puts a
}


z=gets.chop
f[z]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.