ASCII 박스 렌더링


11

직무

귀하의 작업은 입력으로 지정된 위치에 ASCII 상자를 출력하는 프로그램을 작성하는 것입니다.

입력

숫자 목록이 제공됩니다. 여기 형식은 당신이 원하는 deliminator를 사용할 수 있다는 점에서, 약간의 유연성 (예를 들면 1,2,3,4, 1 2 3 4, [1,2,3,4]). 이 목록은 4 개의 그룹 xywh으로 구성되며 각 상자를 지정합니다 . 각 상자의 너비와 높이는 2 이상 x이며 width왼쪽에서 오른쪽입니다. y그리고 height맨 아래입니다.

산출

렌더링은 오른쪽에서 왼쪽으로, 오른쪽의 상자가 먼저 그려지고 그 이후의 모든 상자가 위에있는 것으로 생각할 수 있습니다. 후행 공백과 후행 줄 바꿈이 허용됩니다.

겹치는 상자를 처리하는 방법

입력 왼쪽의 상자가 맨 위 상자이며 겹치지 않습니다. 이후의 모든 상자는 상자에 포함되지 않은 공간에서만 렌더링되며 이미 렌더링 된 상자의 테두리를 대체하지 않습니다.

스타일

상자의 스타일은 상당히 표준이며 +모서리, -가로선 및 |세로선에 사용됩니다.

예 :

( >>>입력을 나타냄)

>>>0 0 11 4 7 2 8 4 3 5 8 3
+---------+
|         |
|         |---+
+---------+   |
       |      |
   +---+------+
   |      |
   +------+


>>>0 3 11 4 7 5 8 4 3 8 8 3 4 0 13 5
    +-----------+
    |           |
    |           |
+---------+     |
|         |-----+
|         |---+
+---------+   |
       |      |
   +---+------+
   |      |
   +------+


>>>0 0 2 2
++
++


>>>2 2 5 3 1 1 7 5 0 0 9 7
+-------+
|+-----+|
||+---+||
|||   |||
||+---+||
|+-----+|
+-------+

>>>0 0 3 3 2 0 3 3
+-+-+
| | |
+-+-+

그 가운데 하나가 4 0 13 5아닌 것이 0 4 13 5아닌가?
Neil

처음 두 경우의 하단에서 두 번째 사각형의 경우 x = 7 (x = 0 사각형과 일치)
Level River St

1
주목 해 주셔서 감사합니다. 제 질문에 대한 답변을 거의 쓰지 않으므로이 모든 것이 수작업으로 이루어집니다.
J Atkin

@JAtkin 미안합니다.
코너 O'Brien

괜찮습니다. 책을 읽을 때 자주 그리워합니다.)
J Atkin

답변:


4

APL, 116 바이트

{⎕IO←0⋄K←' '⍴⍨⌽+⌿2 2⍴⌈⌿↑⍵⋄K⊣{x y W H←⍵-⌊.5×⍳4⋄K[Y←y+⍳H;X←x+⍳W]←' '⋄K[Y;A←x+0 W]←'|'⋄K[B←y+0 H;X]←'-'⋄K[B;A]←'+'}¨⌽⍵}

이것은 배열의 배열을 가져와 문자 행렬을 반환하는 함수입니다.

테스트 :

      t1← (0 0 11 4)(8 2 8 4)(3 5 8 3)
      t2← (0 3 11 4)(8 5 8 4)(3 8 8 3)(4 0 13 5)
      t3← (⊂0 0 2 2)
      t4← (2 2 5 3)(1 1 7 5)(0 0 9 7)
      {⎕IO←0⋄K←' '⍴⍨⌽+⌿2 2⍴⌈⌿↑⍵⋄K⊣{x y W H←⍵-⌊.5×⍳4⋄K[Y←y+⍳H;X←x+⍳W]←' '⋄K[Y;A←x+0 W]←'|'⋄K[B←y+0 H;X]←'-'⋄K[B;A]←'+'}¨⌽⍵} ¨ t1 t2 t3 t4
┌───────────────────┬─────────────────────┬────┬───────────┐
│+---------+        │    +-----------+    │++  │+-------+  │
│|         |        │    |           |    │++  │|+-----+|  │
│|         |----+   │    |           |    │    │||+---+||  │
│+---------+    |   │+---------+     |    │    │|||   |||  │
│        |      |   │|         |-----+    │    │||+---+||  │
│   +----+------+   │|         |----+     │    │|+-----+|  │
│   |      |        │+---------+    |     │    │+-------+  │
│   +------+        │        |      |     │    │           │
│                   │   +----+------+     │    │           │
│                   │   |      |          │    │           │
│                   │   +------+          │    │           │
│                   │                     │    │           │
│                   │                     │    │           │
└───────────────────┴─────────────────────┴────┴───────────┘

설명:

  • ⎕IO←0: 인덱스 원점을로 설정하십시오 0.
  • 올바른 크기의 행렬을 만듭니다.
    • ⌈⌿↑⍵: x, y, w 및 h에 대한 가장 큰 값을 찾습니다
    • +⌿2 2⍴: x + w 및 y + h
    • K←' '⍴⍨⌽: x + w * y + h 공백의 행렬을 만들어에 저장합니다 K.
  • 상자를 그립니다 :
    • {... }¨⌽⍵: 각 상자마다 역순으로
      • x y W H←⍵-⌊.5×⍳4님의 좌표를 지정 x, y, W, 그리고 H, 모두에서 1을 빼야 W하고 H. (좌표는 독점적이며 APL 배열 범위는 포함 적입니다.)
      • K[Y←y+⍳H;X←x+⍳W]←' ': 현재 상자를 공백으로 채 웁니다.
      • K[Y;A←x+0 W]←'|': 세로면 그리기
      • K[B←y+0 H;X]←'-': 수평면을 그립니다.
      • K[B;A]←'+': 모서리를 '+'로 설정
    • K⊣: 나중에 돌아갑니다 K.

1
APL은 외부인에게 이상한 언어입니다.
J Atkin

3

ES6, 228 223 217 208 201 198 바이트

좌표 배열을 받아들이고 문자열을 반환합니다.

a=>a.reverse().map(([x,y,w,h])=>[...Array(y+h)].map((_,i)=>(s=r[i]||'',r[i]=i<y?s:(s+' '.repeat(x)).slice(0,x)+(c=>c[0]+c[1].repeat(w-2)+c[0])(y-i&&y+h-1-i?'| ':'+-')+s.slice(x+w))),r=[])&&r.join`\n`

어디에서 \n개행 문자를 나타냅니다.

편집 : 내 조건을 반대로하여 5 바이트를 절약했습니다. char 배열의 배열에서 문자열 배열로 전환하여 6 바이트를 더 절약했습니다. 임시 변수를 도입하여 추가 9 바이트를 절약했습니다. 도우미 기능을 도입하여 추가로 7 바이트를 절약했습니다. 이전 저장을 취소하여 3 바이트를 더 절약했습니다!


3

루비, 153 143

->n{a=(0..m=3*n.max).map{$b=' '*m}
(*n,x,y,w,h=n 
v=w-2
h.times{|i|a[y+i][x,w]=i%~-h<1??++?-*v+?+:?|+' '*v+?|}
)while n[0]
a.delete($b);puts a}

테스트 프로그램에서 언 골프

f=->n{                                #worst case width when x=w=large number, is max input*2+1
  a=(1..m=3*n.max).map{$b=' '*m}      #find m=max value in input, make an a array of 3*m strings of 3*m spaces 
  (
    *n,x,y,w,h=n                      #extract x,y,w,h from the end of n, save the rest back to n     
    v=w-2                             #internal space in rectangle is w-2  
    h.times{|i|                       #for each row
      a[y+i][x,w]=                    #substitute the relevant characters of the relevant lines of a 
      i%~-h<1?                        #i%~-h = i%(h-1). This is zero (<1) for first and last lines of the rectangle
      ?+ + ?-*v + ?+ :?| + ' '*v +?|  # +--...--+ or |  ...  | as required
    }
  )while n[0]                         #loop until data exhausted (n[0] becomes falsy as it does not exist)
a.delete($b);puts a}                  #delete blank rows ($b is a global variable) and display

3

SmileBASIC, 128 , 125 바이트

DEF B A
WHILE LEN(A)H=POP(A)W=POP(A)-2Y=POP(A)X=POP(A)FOR I=0TO H-1LOCATE X,Y+I?"+|"[M];"- "[M]*W;"+|"[M]M=I<H-2NEXT
WEND
END

스크린 샷 (자른)

스크린 샷 스크린 샷 스크린 샷 스크린 샷 스크린 샷

설명

DEF B A 'make a function and add 12 bytes :(
 WHILE LEN(A) 'repeat until array is empty
  H=POP(A):W=POP(A)-2 'get width/height
  Y=POP(A):X=POP(A) 'get x/y
  FOR I=0 TO H-1 'draw one row at a time
   LOCATE X,Y+I 'position the cursor
   PRINT "+|"[M]; 'draw left edge
   PRINT "- "[M]*W; 'draw middle
   PRINT "+|"[M] 'draw right edge
   M=I<H-2
  NEXT
 WEND
END

M상자의 첫 번째 / 마지막 행에 있는지 여부를 저장합니다 ( 0= +--+, 1= | |). 루프를 통과하는 첫 번째 패스 M에서는 0이고 다른 모든 패스 에서는 마지막까지 1입니다.


:)
J 앳킨


1

Pyth, 162 145 바이트

J\+K*h.MZm+@d1@d3Q]*h.MZm+@d0@d2QdD:GHb XKHX@KHGb;V_QDlTR@NTVl3Vl2:+l0b+l1H?|qHtl3qH0\-?|qbtl2qb0\|d)):l0l1J:+l0tl2l1J:l0+l1tl3J:+l0tl2+l1tl3J;jK

여기서 시도해 볼 수 있습니다

테스트 스위트의 출력 :

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

++
++

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

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

끔찍한 해결책! 누군가 이길 때까지 기다립니다


2
첫 번째 예는 상자가 가장자리를 공유하는 곳에 여분의 +를 넣습니다.
Linus
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.